diff --git a/src/quadpype/hosts/blender/api/ops.py b/src/quadpype/hosts/blender/api/ops.py
index d951d4c8fd..b45bf69d45 100644
--- a/src/quadpype/hosts/blender/api/ops.py
+++ b/src/quadpype/hosts/blender/api/ops.py
@@ -405,7 +405,7 @@ class TOPBAR_MT_avalon(bpy.types.Menu):
"""Avalon menu."""
bl_idname = "TOPBAR_MT_avalon"
- bl_label = os.getenv("QUADPYPE_LABEL")
+ bl_label = os.getenv("QUADPYPE_LABEL") or "QuadPype"
def draw(self, context):
"""Draw the menu in the UI."""
diff --git a/src/quadpype/hosts/flame/api/scripts/wiretap_com.py b/src/quadpype/hosts/flame/api/scripts/wiretap_com.py
index 78bf9ac554..63d403b79d 100644
--- a/src/quadpype/hosts/flame/api/scripts/wiretap_com.py
+++ b/src/quadpype/hosts/flame/api/scripts/wiretap_com.py
@@ -1,14 +1,15 @@
#!/usr/bin/env python2.7
# -*- coding: utf-8 -*-
-
-from __future__ import absolute_import
import os
import sys
import subprocess
import json
+
+from __future__ import absolute_import
import xml.dom.minidom as minidom
from copy import deepcopy
-import datetime
+from datetime import datetime, timezone
+
from libwiretapPythonClientAPI import ( # noqa
WireTapClientInit,
WireTapClientUninit,
@@ -261,7 +262,7 @@ def _user_prep(self, user_name):
return filtered_users.pop()
# create new user name with date in suffix
- now = datetime.datetime.now() # current date and time
+ now = datetime.now(timezone.utc) # current date and time
date = now.strftime("%Y%m%d")
new_user_name = "{}_{}".format(user_name, date)
print(new_user_name)
diff --git a/src/quadpype/hosts/harmony/api/server.py b/src/quadpype/hosts/harmony/api/server.py
index a00c9aaf14..877f66f805 100644
--- a/src/quadpype/hosts/harmony/api/server.py
+++ b/src/quadpype/hosts/harmony/api/server.py
@@ -8,8 +8,10 @@
import functools
import time
import struct
-from datetime import datetime
import threading
+
+from datetime import datetime, timezone
+
from . import lib
@@ -170,18 +172,18 @@ def run(self):
Waits for a connection on `self.port` before going into listen mode.
"""
# Wait for a connection
- timestamp = datetime.now().strftime("%H:%M:%S.%f")
+ timestamp = datetime.now(timezone.utc).strftime("%H:%M:%S.%f")
self.log.debug(f"[{timestamp}] Waiting for a connection.")
self.connection, client_address = self.socket.accept()
- timestamp = datetime.now().strftime("%H:%M:%S.%f")
+ timestamp = datetime.now(timezone.utc).strftime("%H:%M:%S.%f")
self.log.debug(f"[{timestamp}] Connection from: {client_address}")
self.receive()
def stop(self):
"""Shutdown socket server gracefully."""
- timestamp = datetime.now().strftime("%H:%M:%S.%f")
+ timestamp = datetime.now(timezone.utc).strftime("%H:%M:%S.%f")
self.log.debug(f"[{timestamp}] Shutting down server.")
if self.connection is None:
self.log.debug("Connect to shutdown.")
@@ -204,7 +206,7 @@ def _send(self, message):
while not self.connection:
pass
- timestamp = datetime.now().strftime("%H:%M:%S.%f")
+ timestamp = datetime.now(timezone.utc).strftime("%H:%M:%S.%f")
encoded = message.encode("utf-8")
coded_message = b"AH" + struct.pack('>I', len(encoded)) + encoded
pretty = self._pretty(coded_message)
@@ -225,7 +227,7 @@ def send(self, request):
request["message_id"] = self.message_id
self._send(json.dumps(request))
if request.get("reply"):
- timestamp = datetime.now().strftime("%H:%M:%S.%f")
+ timestamp = datetime.now(timezone.utc).strftime("%H:%M:%S.%f")
self.log.debug(
f"[{timestamp}] sent reply, not waiting for anything.")
return None
@@ -235,7 +237,7 @@ def send(self, request):
while True:
time.sleep(0.1)
if time.time() > current_time + 30:
- timestamp = datetime.now().strftime("%H:%M:%S.%f")
+ timestamp = datetime.now(timezone.utc).strftime("%H:%M:%S.%f")
self.log.error((f"[{timestamp}][{self.message_id}] "
"No reply from Harmony in 30s. "
f"Retrying {try_index}"))
@@ -245,7 +247,7 @@ def send(self, request):
break
try:
result = self.queue[request["message_id"]]
- timestamp = datetime.now().strftime("%H:%M:%S.%f")
+ timestamp = datetime.now(timezone.utc).strftime("%H:%M:%S.%f")
self.log.debug((f"[{timestamp}] Got request "
f"id {self.message_id}, "
"removing from queue"))
@@ -276,4 +278,4 @@ def timestamp(self):
str: current timestamp.
"""
- return datetime.now().strftime("%H:%M:%S.%f")
+ return datetime.now(timezone.utc).strftime("%H:%M:%S.%f")
diff --git a/src/quadpype/hosts/nuke/vendor/google/protobuf/internal/well_known_types.py b/src/quadpype/hosts/nuke/vendor/google/protobuf/internal/well_known_types.py
index b581ab750a..5c8fc6db11 100644
--- a/src/quadpype/hosts/nuke/vendor/google/protobuf/internal/well_known_types.py
+++ b/src/quadpype/hosts/nuke/vendor/google/protobuf/internal/well_known_types.py
@@ -42,7 +42,8 @@
import calendar
import collections.abc
-import datetime
+
+from datetime import datetime, timezone, timedelta
from google.protobuf.descriptor import FieldDescriptor
@@ -160,8 +161,8 @@ def FromJsonString(self, value):
raise ValueError(
'time data \'{0}\' does not match format \'%Y-%m-%dT%H:%M:%S\', '
'lowercase \'t\' is not accepted'.format(second_value))
- date_object = datetime.datetime.strptime(second_value, _TIMESTAMPFOMAT)
- td = date_object - datetime.datetime(1970, 1, 1)
+ date_object = datetime.strptime(second_value, _TIMESTAMPFOMAT)
+ td = date_object - datetime(1970, 1, 1)
seconds = td.seconds + td.days * _SECONDS_PER_DAY
if len(nano_value) > 9:
raise ValueError(
@@ -192,7 +193,7 @@ def FromJsonString(self, value):
def GetCurrentTime(self):
"""Get the current UTC into Timestamp."""
- self.FromDatetime(datetime.datetime.utcnow())
+ self.FromDatetime(datetime.now(timezone.utc))
def ToNanoseconds(self):
"""Converts Timestamp to nanoseconds since epoch."""
@@ -244,7 +245,7 @@ def ToDatetime(self, tzinfo=None):
Otherwise, returns a timezone-aware datetime in the input timezone.
"""
- delta = datetime.timedelta(
+ delta = timedelta(
seconds=self.seconds,
microseconds=_RoundTowardZero(self.nanos, _NANOS_PER_MICROSECOND))
if tzinfo is None:
@@ -382,7 +383,7 @@ def FromSeconds(self, seconds):
def ToTimedelta(self):
"""Converts Duration to timedelta."""
- return datetime.timedelta(
+ return timedelta(
seconds=self.seconds, microseconds=_RoundTowardZero(
self.nanos, _NANOS_PER_MICROSECOND))
diff --git a/src/quadpype/hosts/webpublisher/lib.py b/src/quadpype/hosts/webpublisher/lib.py
index 9e2d14df58..e15047f215 100644
--- a/src/quadpype/hosts/webpublisher/lib.py
+++ b/src/quadpype/hosts/webpublisher/lib.py
@@ -1,8 +1,9 @@
import os
-from datetime import datetime
import collections
import json
+from datetime import datetime, timezone
+
from bson.objectid import ObjectId
import pyblish.util
@@ -125,7 +126,7 @@ def start_webpublish_log(dbcon, batch_id, user):
"""
return dbcon.insert_one({
"batch_id": batch_id,
- "start_date": datetime.now(),
+ "start_date": datetime.now(timezone.utc),
"user": user,
"status": IN_PROGRESS_STATUS,
"progress": 0 # integer 0-100, percentage
@@ -168,7 +169,7 @@ def publish_and_log(dbcon, _id, log, close_plugin_name=None, batch_id=None):
{"_id": _id},
{"$set":
{
- "finish_date": datetime.now(),
+ "finish_date": datetime.now(timezone.utc),
"status": ERROR_STATUS,
"log": os.linesep.join(log_lines)
@@ -197,7 +198,7 @@ def publish_and_log(dbcon, _id, log, close_plugin_name=None, batch_id=None):
{
"$set":
{
- "finish_date": datetime.now(),
+ "finish_date": datetime.now(timezone.utc),
"status": FINISHED_REPROCESS_STATUS,
}
}
@@ -208,7 +209,7 @@ def publish_and_log(dbcon, _id, log, close_plugin_name=None, batch_id=None):
{
"$set":
{
- "finish_date": datetime.now(),
+ "finish_date": datetime.now(timezone.utc),
"status": FINISHED_OK_STATUS,
"progress": 100,
"log": os.linesep.join(log_lines)
@@ -227,7 +228,7 @@ def fail_batch(_id, dbcon, msg):
{"_id": _id},
{"$set":
{
- "finish_date": datetime.now(),
+ "finish_date": datetime.now(timezone.utc),
"status": ERROR_STATUS,
"log": msg
diff --git a/src/quadpype/hosts/webpublisher/webserver_service/webpublish_routes.py b/src/quadpype/hosts/webpublisher/webserver_service/webpublish_routes.py
index b3d27556ef..ea7ff211d9 100644
--- a/src/quadpype/hosts/webpublisher/webserver_service/webpublish_routes.py
+++ b/src/quadpype/hosts/webpublisher/webserver_service/webpublish_routes.py
@@ -1,9 +1,11 @@
"""Routes and etc. for webpublisher API."""
import os
import json
-import datetime
import collections
import subprocess
+
+from datetime import datetime
+
from bson.objectid import ObjectId
from fastapi import Response, status
@@ -44,7 +46,7 @@ class JsonApiResource:
"""
@staticmethod
def json_dump_handler(value):
- if isinstance(value, datetime.datetime):
+ if isinstance(value, datetime):
return value.isoformat()
if isinstance(value, ObjectId):
return str(value)
diff --git a/src/quadpype/hosts/webpublisher/webserver_service/webserver.py b/src/quadpype/hosts/webpublisher/webserver_service/webserver.py
index bef2440102..ac141cbad5 100644
--- a/src/quadpype/hosts/webpublisher/webserver_service/webserver.py
+++ b/src/quadpype/hosts/webpublisher/webserver_service/webserver.py
@@ -1,7 +1,7 @@
import collections
import time
import os
-from datetime import datetime
+from datetime import datetime, timezone
import requests
import json
import subprocess
@@ -147,7 +147,7 @@ def reprocess_failed(upload_dir, webserver_url):
{"_id": batch["_id"]},
{"$set":
{
- "finish_date": datetime.now(),
+ "finish_date": datetime.now(timezone.utc),
"status": ERROR_STATUS,
"progress": 100,
"log": batch.get("log") + msg
@@ -166,7 +166,7 @@ def reprocess_failed(upload_dir, webserver_url):
},
{
"$set": {
- "finish_date": datetime.now(),
+ "finish_date": datetime.now(timezone.utc),
"status": SENT_REPROCESSING_STATUS,
"progress": 100
}
diff --git a/src/quadpype/lib/cache.py b/src/quadpype/lib/cache.py
index 023c296335..4846630ee3 100644
--- a/src/quadpype/lib/cache.py
+++ b/src/quadpype/lib/cache.py
@@ -2,7 +2,8 @@
"""Module storing class for caching values, used for settings."""
import json
import copy
-import datetime
+
+from datetime import datetime, timezone
class CacheValues:
@@ -21,7 +22,7 @@ def data_copy(self):
def update_data(self, data, version):
self.data = data
- self.creation_time = datetime.datetime.now()
+ self.creation_time = datetime.now(timezone.utc)
self.version = version
def update_last_saved_info(self, last_saved_info):
@@ -47,7 +48,7 @@ def to_json_string(self):
def is_outdated(self):
if self.creation_time is None:
return True
- delta = (datetime.datetime.now() - self.creation_time).seconds
+ delta = (datetime.now(timezone.utc) - self.creation_time).seconds
return delta > self.cache_lifetime
def set_outdated(self):
diff --git a/src/quadpype/lib/dateutils.py b/src/quadpype/lib/dateutils.py
index b00cdd012b..c88644ad8c 100644
--- a/src/quadpype/lib/dateutils.py
+++ b/src/quadpype/lib/dateutils.py
@@ -35,7 +35,7 @@ def get_datetime_data(datetime_obj=None):
"""
if not datetime_obj:
- datetime_obj = datetime.now()
+ datetime_obj = datetime.now(timezone.utc)
year = datetime_obj.strftime("%Y")
@@ -80,7 +80,7 @@ def get_timestamp_str(datetime_obj=None, local_timezone=False):
"""Get standardized timestamp string from a datetime object.
Args:
- datetime_obj (datetime.datetime): Object of datetime. Current time
+ datetime_obj (datetime): Object of datetime. Current time
is used if not passed.
"""
diff --git a/src/quadpype/lib/log.py b/src/quadpype/lib/log.py
index 0b46c97e51..94807ca297 100644
--- a/src/quadpype/lib/log.py
+++ b/src/quadpype/lib/log.py
@@ -10,9 +10,6 @@
Best place for it is in ``repos/pype-config/environments/global.json``
"""
-
-
-import datetime
import getpass
import logging
import os
@@ -24,6 +21,8 @@
import threading
import copy
+from datetime import datetime, timezone
+
from quadpype.client.mongo import (
MongoEnvNotSet,
get_default_components,
@@ -131,7 +130,7 @@ def format(self, record):
"""Formats LogRecord into python dictionary."""
# Standard document
document = {
- 'timestamp': datetime.datetime.now(),
+ 'timestamp': datetime.now(timezone.utc),
'level': record.levelname,
'thread': record.thread,
'threadName': record.threadName,
diff --git a/src/quadpype/lib/project_backpack.py b/src/quadpype/lib/project_backpack.py
index 342af6789b..cdb179a9a7 100644
--- a/src/quadpype/lib/project_backpack.py
+++ b/src/quadpype/lib/project_backpack.py
@@ -19,9 +19,10 @@
import platform
import tempfile
import shutil
-import datetime
-
import zipfile
+
+from datetime import datetime, timezone
+
from quadpype.client.mongo import (
load_json_file,
get_project_connection,
@@ -37,7 +38,7 @@
def add_timestamp(filepath):
"""Add timestamp string to a file."""
base, ext = os.path.splitext(filepath)
- timestamp = datetime.datetime.now().strftime("%y%m%d_%H%M%S")
+ timestamp = datetime.now(timezone.utc).strftime("%y%m%d_%H%M%S")
new_base = "{}_{}".format(base, timestamp)
return new_base + ext
diff --git a/src/quadpype/lib/pype_info.py b/src/quadpype/lib/pype_info.py
index 5496a20cfc..b41f0a2676 100644
--- a/src/quadpype/lib/pype_info.py
+++ b/src/quadpype/lib/pype_info.py
@@ -1,6 +1,6 @@
import os
import json
-import datetime
+from datetime import datetime, timezone
from .execute import get_quadpype_execute_args
from .user import get_user_id, get_user_profile
@@ -58,7 +58,7 @@ def extract_pype_info_to_file(dir_path):
filename = "{}_{}_{}.json".format(
get_quadpype_version(),
get_user_id(),
- datetime.datetime.now().strftime("%y%m%d%H%M%S")
+ datetime.now(timezone.utc).strftime("%y%m%d%H%M%S")
)
filepath = os.path.join(dir_path, filename)
data = get_all_current_info()
diff --git a/src/quadpype/lib/registry.py b/src/quadpype/lib/registry.py
index a5d35222b4..21b211954b 100644
--- a/src/quadpype/lib/registry.py
+++ b/src/quadpype/lib/registry.py
@@ -3,7 +3,7 @@
import os
import json
import platform
-from datetime import datetime
+from datetime import datetime, timezone
from abc import ABC, abstractmethod
from functools import lru_cache
import configparser
@@ -227,7 +227,7 @@ def __init__(self, name, path):
with open(self._registry_file, mode="w") as cfg:
print("# Settings registry", cfg)
print("# Generated by QuadPype {}".format(version), cfg)
- now = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
+ now = datetime.now(timezone.utc).strftime("%d/%m/%Y %H:%M:%S")
print("# {}".format(now), cfg)
def set_item_section(
@@ -376,7 +376,7 @@ def __init__(self, name, path, base_version=None):
super(JSONSettingRegistry, self).__init__(name)
#: str: name of registry file
self._registry_file = os.path.join(path, "{}.json".format(name))
- now = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
+ now = datetime.now(timezone.utc).strftime("%d/%m/%Y %H:%M:%S")
if not base_version:
base_version = "N/A"
diff --git a/src/quadpype/lib/user.py b/src/quadpype/lib/user.py
index 3007396000..16ae91e5fc 100644
--- a/src/quadpype/lib/user.py
+++ b/src/quadpype/lib/user.py
@@ -3,10 +3,11 @@
import os
import copy
import getpass
-import datetime
import functools
import platform
import socket
+
+from datetime import datetime, timezone
from abc import ABC, abstractmethod
from .registry import get_app_registry
@@ -27,8 +28,8 @@ class UserHandler(ABC):
user_profile_template = {
"user_id": "",
"role": "user",
- "first_connection_timestamp": datetime.datetime.now(),
- "last_connection_timestamp": datetime.datetime.now(),
+ "first_connection_timestamp": datetime.now(timezone.utc),
+ "last_connection_timestamp": datetime.now(timezone.utc),
"last_workstation_profile_index": 0,
"workstation_profiles": [],
"settings": {}
@@ -103,7 +104,7 @@ def create_user_profile(self, user_role="user"):
user_profile["user_id"] = self.user_id
user_profile["role"] = user_role
- timestamp = datetime.datetime.now()
+ timestamp = datetime.now(timezone.utc)
user_profile["first_connection_timestamp"] = timestamp
user_profile["last_connection_timestamp"] = timestamp
@@ -131,7 +132,7 @@ def get_all_user_profiles(self):
def update_user_profile_on_startup(self):
"""Update user profile on startup"""
user_profile = self.get_user_profile()
- user_profile["last_connection_timestamp"] = datetime.datetime.now()
+ user_profile["last_connection_timestamp"] = datetime.now(timezone.utc)
workstation_info = get_user_workstation_info()
diff --git a/src/quadpype/modules/base.py b/src/quadpype/modules/base.py
index d1920be3cb..34e9f83b71 100644
--- a/src/quadpype/modules/base.py
+++ b/src/quadpype/modules/base.py
@@ -1155,7 +1155,6 @@ class TrayModulesManager(ModulesManager):
"clockify", # Clockify
"sync_server", # Sync Queue
# More Tools Submenu -----------------------------
- "update_zxp_extensions", # Update ZXP Extensions
"log_viewer", # Show Logs
"python_interpreter", # Console
# Admin Submenu ----------------------------------
diff --git a/src/quadpype/modules/clockify/clockify_api.py b/src/quadpype/modules/clockify/clockify_api.py
index 2b57958d14..4aea8c0a02 100644
--- a/src/quadpype/modules/clockify/clockify_api.py
+++ b/src/quadpype/modules/clockify/clockify_api.py
@@ -1,6 +1,8 @@
import os
import json
-import datetime
+
+from datetime import datetime, timezone
+
import requests
from .constants import (
CLOCKIFY_ENDPOINT,
@@ -221,7 +223,7 @@ def get_task_id(self, task_name, project_id, workspace_id=None):
return all_tasks[task_name]
def get_current_time(self):
- return str(datetime.datetime.utcnow().isoformat()) + "Z"
+ return datetime.now(timezone.utc).isoformat()
def start_time_entry(
self,
diff --git a/src/quadpype/modules/deadline/aftereffects/publish/submit_aftereffects_deadline.py b/src/quadpype/modules/deadline/aftereffects/publish/submit_aftereffects_deadline.py
index fb9bef99ca..be43a1f6a9 100644
--- a/src/quadpype/modules/deadline/aftereffects/publish/submit_aftereffects_deadline.py
+++ b/src/quadpype/modules/deadline/aftereffects/publish/submit_aftereffects_deadline.py
@@ -2,7 +2,8 @@
import attr
import getpass
import pyblish.api
-from datetime import datetime
+
+from datetime import datetime, timezone
from quadpype.lib import (
env_value_to_bool,
@@ -65,7 +66,7 @@ def get_job_info(self):
)
if is_in_tests():
- batch_name += datetime.now().strftime("%d%m%Y%H%M%S")
+ batch_name += datetime.now(timezone.utc).strftime("%d%m%Y%H%M%S")
dln_job_info.Name = job_name
dln_job_info.BatchName = "Group: " + batch_name
dln_job_info.Plugin = "AfterEffects"
diff --git a/src/quadpype/modules/deadline/blender/publish/submit_blender_deadline.py b/src/quadpype/modules/deadline/blender/publish/submit_blender_deadline.py
index 51a87fd8b6..d6ac36694a 100644
--- a/src/quadpype/modules/deadline/blender/publish/submit_blender_deadline.py
+++ b/src/quadpype/modules/deadline/blender/publish/submit_blender_deadline.py
@@ -4,7 +4,8 @@
import os
import getpass
import attr
-from datetime import datetime
+
+from datetime import datetime, timezone
from quadpype.lib import (
is_running_from_build,
@@ -58,7 +59,7 @@ def get_job_info(self):
src_filename = os.path.basename(src_filepath)
if is_in_tests():
- src_filename += datetime.now().strftime("%d%m%Y%H%M%S")
+ src_filename += datetime.now(timezone.utc).strftime("%d%m%Y%H%M%S")
job_info.Name = f"{src_filename} - {instance.name}"
job_info.BatchName = src_filename
diff --git a/src/quadpype/modules/deadline/harmony/publish/submit_harmony_deadline.py b/src/quadpype/modules/deadline/harmony/publish/submit_harmony_deadline.py
index 79b77e05c9..1cd41efab5 100644
--- a/src/quadpype/modules/deadline/harmony/publish/submit_harmony_deadline.py
+++ b/src/quadpype/modules/deadline/harmony/publish/submit_harmony_deadline.py
@@ -5,7 +5,8 @@
from collections import OrderedDict
from zipfile import ZipFile, is_zipfile
import re
-from datetime import datetime
+
+from datetime import datetime, timezone
import attr
import pyblish.api
@@ -276,7 +277,7 @@ def get_job_info(self):
"deadline_batch_name"
)
if is_in_tests():
- batch_name += datetime.now().strftime("%d%m%Y%H%M%S")
+ batch_name += datetime.now(timezone.utc).strftime("%d%m%Y%H%M%S")
job_info.BatchName = "Group: " + batch_name
job_info.Name = job_name
job_info.BatchName = batch_name
diff --git a/src/quadpype/modules/deadline/houdini/publish/submit_houdini_cache_deadline.py b/src/quadpype/modules/deadline/houdini/publish/submit_houdini_cache_deadline.py
index 36131d88cb..0ecbdc47ff 100644
--- a/src/quadpype/modules/deadline/houdini/publish/submit_houdini_cache_deadline.py
+++ b/src/quadpype/modules/deadline/houdini/publish/submit_houdini_cache_deadline.py
@@ -1,6 +1,7 @@
import os
import getpass
-from datetime import datetime
+
+from datetime import datetime, timezone
import attr
import pyblish.api
@@ -80,7 +81,7 @@ def get_job_info(self):
batch_name = "{code} - {scene}".format(code=project_name,
scene=scenename)
if is_in_tests():
- batch_name += datetime.now().strftime("%d%m%Y%H%M%S")
+ batch_name += datetime.now(timezone.utc).strftime("%d%m%Y%H%M%S")
job_info.Name = job_name
job_info.BatchName = batch_name
diff --git a/src/quadpype/modules/deadline/houdini/publish/submit_houdini_remote_publish.py b/src/quadpype/modules/deadline/houdini/publish/submit_houdini_remote_publish.py
index a2c51866ac..6f2d91724b 100644
--- a/src/quadpype/modules/deadline/houdini/publish/submit_houdini_remote_publish.py
+++ b/src/quadpype/modules/deadline/houdini/publish/submit_houdini_remote_publish.py
@@ -1,7 +1,8 @@
import os
import json
import getpass
-from datetime import datetime
+
+from datetime import datetime, timezone
import requests
@@ -72,7 +73,7 @@ def process(self, context):
job_name = "{scene} [PUBLISH]".format(scene=scenename)
batch_name = "{code} - {scene}".format(code=code, scene=scenename)
if is_in_tests():
- batch_name += datetime.now().strftime("%d%m%Y%H%M%S")
+ batch_name += datetime.now(timezone.utc).strftime("%d%m%Y%H%M%S")
deadline_user = context.data.get("deadlineUser", getpass.getuser())
# Get only major.minor version of Houdini, ignore patch version
diff --git a/src/quadpype/modules/deadline/houdini/publish/submit_houdini_render_deadline.py b/src/quadpype/modules/deadline/houdini/publish/submit_houdini_render_deadline.py
index e971734638..a48f1cb610 100644
--- a/src/quadpype/modules/deadline/houdini/publish/submit_houdini_render_deadline.py
+++ b/src/quadpype/modules/deadline/houdini/publish/submit_houdini_render_deadline.py
@@ -1,7 +1,8 @@
import os
import attr
import getpass
-from datetime import datetime
+
+from datetime import datetime, timezone
import pyblish.api
@@ -182,7 +183,7 @@ def get_job_info(self, dependency_job_ids=None):
"deadlineUser", getpass.getuser())
if is_in_tests():
- job_info.BatchName += datetime.now().strftime("%d%m%Y%H%M%S")
+ job_info.BatchName += datetime.now(timezone.utc).strftime("%d%m%Y%H%M%S")
# Deadline requires integers in frame range
start = instance.data["frameStartHandle"]
diff --git a/src/quadpype/modules/deadline/maya/publish/submit_maya_deadline.py b/src/quadpype/modules/deadline/maya/publish/submit_maya_deadline.py
index add4982ced..2171d0fe80 100644
--- a/src/quadpype/modules/deadline/maya/publish/submit_maya_deadline.py
+++ b/src/quadpype/modules/deadline/maya/publish/submit_maya_deadline.py
@@ -22,7 +22,7 @@
import copy
import re
import hashlib
-from datetime import datetime
+from datetime import datetime, timezone
import itertools
from collections import OrderedDict
@@ -155,7 +155,7 @@ def get_job_info(self):
)
if is_in_tests():
- batch_name += datetime.now().strftime("%d%m%Y%H%M%S")
+ batch_name += datetime.now(timezone.utc).strftime("%d%m%Y%H%M%S")
job_info.Name = job_name
job_info.BatchName = "Group: " + batch_name
@@ -498,7 +498,7 @@ def _tile_render(self, payload):
output_dir,
"{}_config_{}.txt".format(
os.path.splitext(file)[0],
- datetime.now().strftime("%Y_%m_%d_%H_%M_%S")
+ datetime.now(timezone.utc).strftime("%Y_%m_%d_%H_%M_%S")
)
)
config_files.append(config_file)
diff --git a/src/quadpype/modules/deadline/maya/publish/submit_maya_remote_publish_deadline.py b/src/quadpype/modules/deadline/maya/publish/submit_maya_remote_publish_deadline.py
index 33fe7dedd8..816c089f8c 100644
--- a/src/quadpype/modules/deadline/maya/publish/submit_maya_remote_publish_deadline.py
+++ b/src/quadpype/modules/deadline/maya/publish/submit_maya_remote_publish_deadline.py
@@ -1,6 +1,7 @@
import os
import attr
-from datetime import datetime
+
+from datetime import datetime, timezone
from quadpype.settings import PROJECT_SETTINGS_KEY
from quadpype.pipeline import legacy_io, PublishXmlValidationError
@@ -90,7 +91,7 @@ def get_job_info(self):
)
if is_in_tests():
- batch_name += datetime.now().strftime("%d%m%Y%H%M%S")
+ batch_name += datetime.now(timezone.utc).strftime("%d%m%Y%H%M%S")
job_info = DeadlineJobInfo(Plugin="MayaBatch")
job_info.BatchName = "Group: " + batch_name,
diff --git a/src/quadpype/modules/deadline/nuke/publish/submit_nuke_deadline.py b/src/quadpype/modules/deadline/nuke/publish/submit_nuke_deadline.py
index 2df581ce07..810915e60a 100644
--- a/src/quadpype/modules/deadline/nuke/publish/submit_nuke_deadline.py
+++ b/src/quadpype/modules/deadline/nuke/publish/submit_nuke_deadline.py
@@ -3,7 +3,8 @@
import json
import getpass
import platform
-from datetime import datetime
+
+from datetime import datetime, timezone
import requests
import pyblish.api
@@ -322,7 +323,7 @@ def payload_submit(
)
if is_in_tests():
- batch_name += datetime.now().strftime("%d%m%Y%H%M%S")
+ batch_name += datetime.now(timezone.utc).strftime("%d%m%Y%H%M%S")
output_filename_0 = self.preview_fname(render_path)
diff --git a/src/quadpype/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py b/src/quadpype/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py
index f987870beb..9a13a85c3b 100644
--- a/src/quadpype/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py
+++ b/src/quadpype/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py
@@ -2,17 +2,17 @@
# -*- coding: utf-8 -*-
import os
import tempfile
-from datetime import datetime
+from datetime import datetime, timezone
import subprocess
import json
import platform
import uuid
import re
+
from Deadline.Scripting import (
RepositoryUtils,
FileUtils,
- DirectoryUtils,
- ProcessUtils,
+ DirectoryUtils
)
VERSION_REGEX = re.compile(
@@ -323,7 +323,7 @@ def inject_quadpype_environment(deadlinePlugin):
# tempfile.TemporaryFile cannot be used because of locking
temp_file_name = "{}_{}.json".format(
- datetime.utcnow().strftime('%Y%m%d%H%M%S%f'),
+ datetime.now(timezone.utc).strftime('%Y%m%d%H%M%S%f'),
str(uuid.uuid1())
)
export_url = os.path.join(tempfile.gettempdir(), temp_file_name)
diff --git a/src/quadpype/modules/ftrack/event_handlers_server/action_create_review_session.py b/src/quadpype/modules/ftrack/event_handlers_server/action_create_review_session.py
index e7c9624181..cdd01cce30 100644
--- a/src/quadpype/modules/ftrack/event_handlers_server/action_create_review_session.py
+++ b/src/quadpype/modules/ftrack/event_handlers_server/action_create_review_session.py
@@ -1,8 +1,9 @@
import threading
-import datetime
import copy
import collections
+from datetime import datetime, timezone, timedelta
+
import ftrack_api
from quadpype.lib import get_datetime_data
@@ -46,7 +47,7 @@ def __init__(self, *args, **kwargs):
self._cycle_timer = None
self._last_cyle_time = None
- self._day_delta = datetime.timedelta(days=1)
+ self._day_delta = timedelta(days=1)
def discover(self, session, entities, event):
"""Show action only on AssetVersions."""
@@ -99,11 +100,9 @@ def _calculate_next_cycle_delta(self):
# Create threading timer which will trigger creation of report
# at the 00:00:01 of next day
# - callback will trigger another timer which will have 1 day offset
- now = datetime.datetime.now()
+ now = datetime.now(timezone.utc)
# Create object of today morning
- expected_next_trigger = datetime.datetime(
- now.year, now.month, now.day, h, m, s
- )
+ expected_next_trigger = datetime(now.year, now.month, now.day, h, m, s, tzinfo=timezone.utc)
if expected_next_trigger > now:
seconds = (expected_next_trigger - now).total_seconds()
else:
@@ -199,10 +198,8 @@ def _process_review_session(
review_sessions_by_project_id[project_id].append(review_session)
# Prepare fill data for today's review sesison and yesterdays
- now = datetime.datetime.now()
- today_obj = datetime.datetime(
- now.year, now.month, now.day, 0, 0, 0
- )
+ now = datetime.now(timezone.utc)
+ today_obj = datetime(now.year, now.month, now.day, 0, 0, 0, tzinfo=timezone.utc)
yesterday_obj = today_obj - self._day_delta
today_fill_data = get_datetime_data(today_obj)
diff --git a/src/quadpype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py b/src/quadpype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py
index bfb4936561..4211818886 100644
--- a/src/quadpype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py
+++ b/src/quadpype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py
@@ -2,10 +2,11 @@
import copy
import json
import time
-import datetime
import atexit
import traceback
+from datetime import datetime, timezone
+
from bson.objectid import ObjectId
from pymongo import UpdateOne
@@ -85,7 +86,7 @@ def __init__(self, session):
# - time expiration in seconds
self.debug_print_time_expiration = 5 * 60
# - store current time
- self.debug_print_time = datetime.datetime.now()
+ self.debug_print_time = datetime.now(timezone.utc)
# - store synchronize entity types to be able to use
# only entityTypes in interest instead of filtering by ignored
self.debug_sync_types = collections.defaultdict(list)
@@ -97,7 +98,7 @@ def __init__(self, session):
def debug_logs(self):
"""This is debug method for printing small debugs messages. """
- now_datetime = datetime.datetime.now()
+ now_datetime = datetime.now(timezone.utc)
delta = now_datetime - self.debug_print_time
if delta.total_seconds() < self.debug_print_time_expiration:
return
diff --git a/src/quadpype/modules/ftrack/event_handlers_user/action_delete_asset.py b/src/quadpype/modules/ftrack/event_handlers_user/action_delete_asset.py
index 64a3901c50..5555edfd6b 100644
--- a/src/quadpype/modules/ftrack/event_handlers_user/action_delete_asset.py
+++ b/src/quadpype/modules/ftrack/event_handlers_user/action_delete_asset.py
@@ -1,6 +1,6 @@
import collections
import uuid
-from datetime import datetime
+from datetime import datetime, timezone
from bson.objectid import ObjectId
@@ -181,7 +181,7 @@ def interface(self, session, entities, event):
if not created_at:
old_action_ids.append(action_id)
continue
- cur_time = datetime.now()
+ cur_time = datetime.now(timezone.utc)
existing_in_sec = (created_at - cur_time).total_seconds()
if existing_in_sec > 60 * 2:
old_action_ids.append(action_id)
@@ -193,7 +193,7 @@ def interface(self, session, entities, event):
action_id = str(uuid.uuid1())
self.action_data_by_id[action_id] = {
"attempt": 1,
- "created_at": datetime.now(),
+ "created_at": datetime.now(timezone.utc),
"project_name": project_name,
"subset_ids_by_name": {},
"subset_ids_by_parent": {},
diff --git a/src/quadpype/modules/ftrack/event_handlers_user/action_fill_workfile_attr.py b/src/quadpype/modules/ftrack/event_handlers_user/action_fill_workfile_attr.py
index f8790b46cc..4cfa0f448e 100644
--- a/src/quadpype/modules/ftrack/event_handlers_user/action_fill_workfile_attr.py
+++ b/src/quadpype/modules/ftrack/event_handlers_user/action_fill_workfile_attr.py
@@ -3,7 +3,7 @@
import json
import collections
import tempfile
-import datetime
+from datetime import datetime, timezone
import ftrack_api
@@ -174,7 +174,7 @@ def launch(self, session, entities, event):
component_name = "{}_{}".format(
"FillWorkfilesReport",
- datetime.datetime.now().strftime("%y-%m-%d-%H%M")
+ datetime.now(timezone.utc).strftime("%y-%m-%d-%H%M")
)
self.add_file_component_to_job(
job_entity, session, temp_filepath, component_name
diff --git a/src/quadpype/modules/ftrack/ftrack_server/event_server_cli.py b/src/quadpype/modules/ftrack/ftrack_server/event_server_cli.py
index c5dd545126..859c822b74 100644
--- a/src/quadpype/modules/ftrack/ftrack_server/event_server_cli.py
+++ b/src/quadpype/modules/ftrack/ftrack_server/event_server_cli.py
@@ -1,6 +1,5 @@
import os
import signal
-import datetime
import subprocess
import socket
import json
@@ -9,6 +8,8 @@
import time
import uuid
+from datetime import datetime, timezone
+
import ftrack_api
import pymongo
from quadpype.client.mongo import (
@@ -109,7 +110,7 @@ def legacy_server(ftrack_url):
subproc = None
subproc_path = "{}/sub_legacy_server.py".format(scripts_dir)
- subproc_last_failed = datetime.datetime.now()
+ subproc_last_failed = datetime.now(timezone.utc)
subproc_failed_count = 0
ftrack_accessible = False
@@ -122,7 +123,7 @@ def legacy_server(ftrack_url):
# Run threads only if Ftrack is accessible
if not ftrack_accessible and not printed_ftrack_error:
print("Can't access Ftrack {} <{}>".format(
- ftrack_url, str(datetime.datetime.now())
+ ftrack_url, str(datetime.now(timezone.utc))
))
if subproc is not None:
if subproc.poll() is None:
@@ -150,7 +151,7 @@ def legacy_server(ftrack_url):
).format(str(max_fail_count), str(wait_time_after_max_fail)))
subproc_failed_count += 1
elif ((
- datetime.datetime.now() - subproc_last_failed
+ datetime.now(timezone.utc) - subproc_last_failed
).seconds > wait_time_after_max_fail):
subproc_failed_count = 0
@@ -159,7 +160,7 @@ def legacy_server(ftrack_url):
subproc = None
ftrack_accessible = False
- _subproc_last_failed = datetime.datetime.now()
+ _subproc_last_failed = datetime.now(timezone.utc)
delta_time = (_subproc_last_failed - subproc_last_failed).seconds
if delta_time < min_fail_seconds:
subproc_failed_count += 1
@@ -197,21 +198,21 @@ def main_loop(ftrack_url):
storer_port = 10001
storer_path = "{}/sub_event_storer.py".format(scripts_dir)
storer_thread = None
- storer_last_failed = datetime.datetime.now()
+ storer_last_failed = datetime.now(timezone.utc)
storer_failed_count = 0
processor_name = "ProcessorThread"
processor_port = 10011
processor_path = "{}/sub_event_processor.py".format(scripts_dir)
processor_thread = None
- processor_last_failed = datetime.datetime.now()
+ processor_last_failed = datetime.now(timezone.utc)
processor_failed_count = 0
statuser_name = "StorerThread"
statuser_port = 10021
statuser_path = "{}/sub_event_status.py".format(scripts_dir)
statuser_thread = None
- statuser_last_failed = datetime.datetime.now()
+ statuser_last_failed = datetime.now(timezone.utc)
statuser_failed_count = 0
ftrack_accessible = False
@@ -249,7 +250,7 @@ def on_exit(processor_thread, storer_thread, statuser_thread):
host_ip = get_host_ip()
main_info = [
- ["created_at", datetime.datetime.now().strftime("%Y.%m.%d %H:%M:%S")],
+ ["created_at", datetime.now(timezone.utc).strftime("%Y.%m.%d %H:%M:%S")],
["Username", getpass.getuser()],
["Host Name", host_name],
["Host IP", host_ip or "N/A"],
@@ -311,7 +312,7 @@ def on_exit(processor_thread, storer_thread, statuser_thread):
statuser_failed_count += 1
elif ((
- datetime.datetime.now() - statuser_last_failed
+ datetime.now(timezone.utc) - statuser_last_failed
).seconds > wait_time_after_max_fail):
statuser_failed_count = 0
@@ -322,7 +323,7 @@ def on_exit(processor_thread, storer_thread, statuser_thread):
ftrack_accessible = False
mongo_accessible = False
- _processor_last_failed = datetime.datetime.now()
+ _processor_last_failed = datetime.now(timezone.utc)
delta_time = (
_processor_last_failed - statuser_last_failed
).seconds
@@ -354,7 +355,7 @@ def on_exit(processor_thread, storer_thread, statuser_thread):
).format(str(max_fail_count), str(wait_time_after_max_fail)))
storer_failed_count += 1
elif ((
- datetime.datetime.now() - storer_last_failed
+ datetime.now(timezone.utc) - storer_last_failed
).seconds > wait_time_after_max_fail):
storer_failed_count = 0
@@ -367,7 +368,7 @@ def on_exit(processor_thread, storer_thread, statuser_thread):
ftrack_accessible = False
mongo_accessible = False
- _storer_last_failed = datetime.datetime.now()
+ _storer_last_failed = datetime.now(timezone.utc)
delta_time = (_storer_last_failed - storer_last_failed).seconds
if delta_time < min_fail_seconds:
storer_failed_count += 1
@@ -391,7 +392,7 @@ def on_exit(processor_thread, storer_thread, statuser_thread):
processor_failed_count += 1
elif ((
- datetime.datetime.now() - processor_last_failed
+ datetime.now(timezone.utc) - processor_last_failed
).seconds > wait_time_after_max_fail):
processor_failed_count = 0
@@ -406,7 +407,7 @@ def on_exit(processor_thread, storer_thread, statuser_thread):
ftrack_accessible = False
mongo_accessible = False
- _processor_last_failed = datetime.datetime.now()
+ _processor_last_failed = datetime.now(timezone.utc)
delta_time = (
_processor_last_failed - processor_last_failed
).seconds
diff --git a/src/quadpype/modules/ftrack/ftrack_server/lib.py b/src/quadpype/modules/ftrack/ftrack_server/lib.py
index f3f4f9ada8..7cd9ce45e7 100644
--- a/src/quadpype/modules/ftrack/ftrack_server/lib.py
+++ b/src/quadpype/modules/ftrack/ftrack_server/lib.py
@@ -4,13 +4,14 @@
import getpass
import atexit
import threading
-import datetime
import time
import queue
import collections
import appdirs
import socket
+from datetime import datetime, timezone, timedelta
+
import pymongo
import requests
import ftrack_api
@@ -186,7 +187,7 @@ def wait(self, duration=None):
def load_events(self):
"""Load not processed events sorted by stored date"""
- ago_date = datetime.datetime.now() - datetime.timedelta(days=3)
+ ago_date = datetime.now(timezone.utc) - timedelta(days=3)
self.dbcon.delete_many({
"pype_data.stored": {"$lte": ago_date},
"pype_data.is_processed": True
diff --git a/src/quadpype/modules/ftrack/lib/ftrack_base_handler.py b/src/quadpype/modules/ftrack/lib/ftrack_base_handler.py
index fbd896da21..fa985472dc 100644
--- a/src/quadpype/modules/ftrack/lib/ftrack_base_handler.py
+++ b/src/quadpype/modules/ftrack/lib/ftrack_base_handler.py
@@ -3,9 +3,11 @@
import json
import functools
import uuid
-import datetime
import traceback
import time
+
+from datetime import datetime, timezone
+
from quadpype.lib import Logger
from quadpype.settings import get_project_settings, PROJECT_SETTINGS_KEY
@@ -670,7 +672,7 @@ def add_traceback_to_job(
if not component_name:
component_name = "{}_{}".format(
cls.__name__,
- datetime.datetime.now().strftime("%y-%m-%d-%H%M")
+ datetime.now(timezone.utc).strftime("%y-%m-%d-%H%M")
)
cls.add_file_component_to_job(
job, session, temp_filepath, component_name
diff --git a/src/quadpype/modules/ftrack/scripts/sub_event_processor.py b/src/quadpype/modules/ftrack/scripts/sub_event_processor.py
index ccd858deea..89916657a9 100644
--- a/src/quadpype/modules/ftrack/scripts/sub_event_processor.py
+++ b/src/quadpype/modules/ftrack/scripts/sub_event_processor.py
@@ -2,7 +2,8 @@
import sys
import signal
import socket
-import datetime
+
+from datetime import datetime, timezone
import ftrack_api
@@ -20,7 +21,7 @@
get_build_version
)
-subprocess_started = datetime.datetime.now()
+subprocess_started = datetime.now(timezone.utc)
class SessionFactory:
diff --git a/src/quadpype/modules/ftrack/scripts/sub_event_status.py b/src/quadpype/modules/ftrack/scripts/sub_event_status.py
index 2dab38f3ea..54be2f0709 100644
--- a/src/quadpype/modules/ftrack/scripts/sub_event_status.py
+++ b/src/quadpype/modules/ftrack/scripts/sub_event_status.py
@@ -5,7 +5,8 @@
import collections
import signal
import socket
-import datetime
+
+from datetime import datetime, timezone
import appdirs
@@ -61,7 +62,7 @@ def __init__(self, name, label, parent):
self.last_update = None
def update(self, info):
- self.last_update = datetime.datetime.now()
+ self.last_update = datetime.now(timezone.utc)
self.info = info
def get_delta_string(self, delta):
@@ -87,7 +88,7 @@ def get_items(self):
items = []
last_update = "N/A"
if self.last_update:
- delta = datetime.datetime.now() - self.last_update
+ delta = datetime.now(timezone.utc) - self.last_update
last_update = "{} ago".format(
self.get_delta_string(delta)
)
@@ -114,10 +115,10 @@ def get_items(self):
info[key] = value
continue
- datetime_value = datetime.datetime.strptime(
+ datetime_value = datetime.strptime(
value, "%Y.%m.%d %H:%M:%S"
)
- delta = datetime.datetime.now() - datetime_value
+ delta = datetime.now(timezone.utc) - datetime_value
running_for = self.get_delta_string(delta)
info["Started at"] = "{} [running: {}]".format(value, running_for)
@@ -358,7 +359,7 @@ def server_activity(event):
def trigger_info_get():
if ObjectFactory.last_trigger:
- delta = datetime.datetime.now() - ObjectFactory.last_trigger
+ delta = datetime.now(timezone.utc) - ObjectFactory.last_trigger
if delta.seconds() < 5:
return
diff --git a/src/quadpype/modules/ftrack/scripts/sub_event_storer.py b/src/quadpype/modules/ftrack/scripts/sub_event_storer.py
index 1781950b6c..9c3cd5dfa6 100644
--- a/src/quadpype/modules/ftrack/scripts/sub_event_storer.py
+++ b/src/quadpype/modules/ftrack/scripts/sub_event_storer.py
@@ -1,10 +1,11 @@
import os
import sys
-import datetime
import signal
import socket
import pymongo
+from datetime import datetime, timezone
+
import ftrack_api
from quadpype.client import QuadPypeMongoConnection
@@ -23,7 +24,7 @@
)
log = Logger.get_logger("Event storer")
-subprocess_started = datetime.datetime.now()
+subprocess_started = datetime.now(timezone.utc)
class SessionFactory:
@@ -57,7 +58,7 @@ def launch(event):
event_id = event["id"]
event_data["pype_data"] = {
- "stored": datetime.datetime.utcnow(),
+ "stored": datetime.now(timezone.utc),
"is_processed": False
}
diff --git a/src/quadpype/modules/ftrack/scripts/sub_legacy_server.py b/src/quadpype/modules/ftrack/scripts/sub_legacy_server.py
index 4f98497a75..8611f5549a 100644
--- a/src/quadpype/modules/ftrack/scripts/sub_legacy_server.py
+++ b/src/quadpype/modules/ftrack/scripts/sub_legacy_server.py
@@ -1,9 +1,10 @@
import sys
import time
-import datetime
import signal
import threading
+from datetime import datetime, timezone
+
import ftrack_api
from quadpype.lib import Logger
from quadpype.modules import ModulesManager
@@ -26,7 +27,7 @@ def stop(self):
self.is_running = False
def run(self):
- start = datetime.datetime.now()
+ start = datetime.now(timezone.utc)
self.is_running = True
connected = False
@@ -37,7 +38,7 @@ def run(self):
if not self.session.event_hub.connected:
if not connected:
if (
- (datetime.datetime.now() - start).seconds >
+ (datetime.now(timezone.utc) - start).seconds >
self.max_time_out
):
log.error((
diff --git a/src/quadpype/modules/ftrack/tray/ftrack_tray.py b/src/quadpype/modules/ftrack/tray/ftrack_tray.py
index 9a109e27c6..2b60c29f60 100644
--- a/src/quadpype/modules/ftrack/tray/ftrack_tray.py
+++ b/src/quadpype/modules/ftrack/tray/ftrack_tray.py
@@ -1,8 +1,9 @@
import os
import time
-import datetime
import threading
+from datetime import datetime, timezone
+
import ftrack_api
from qtpy import QtCore, QtWidgets, QtGui
@@ -136,7 +137,7 @@ def set_action_server(self):
self.thread_socket_server.join()
self.thread_socket_server = None
- last_failed = datetime.datetime.now()
+ last_failed = datetime.now(timezone.utc)
failed_count = 0
ftrack_accessible = False
@@ -193,7 +194,7 @@ def set_action_server(self):
failed_count += 1
elif ((
- datetime.datetime.now() - last_failed
+ datetime.now(timezone.utc) - last_failed
).seconds > wait_time_after_max_fail):
failed_count = 0
@@ -206,7 +207,7 @@ def set_action_server(self):
self.bool_action_thread_running = False
self.set_menu_visibility()
- _last_failed = datetime.datetime.now()
+ _last_failed = datetime.now(timezone.utc)
delta_time = (_last_failed - last_failed).seconds
if delta_time < min_fail_seconds:
failed_count += 1
diff --git a/src/quadpype/modules/job_queue/job_server/jobs.py b/src/quadpype/modules/job_queue/job_server/jobs.py
index 0fc3c381d4..e739af9315 100644
--- a/src/quadpype/modules/job_queue/job_server/jobs.py
+++ b/src/quadpype/modules/job_queue/job_server/jobs.py
@@ -1,7 +1,8 @@
-import datetime
import collections
from uuid import uuid4
+from datetime import datetime, timezone
+
class Job:
"""Job related to specific host name.
@@ -16,7 +17,7 @@ def __init__(self, host_name, data, job_id=None, created_time=None):
job_id = str(uuid4())
self._id = job_id
if created_time is None:
- created_time = datetime.datetime.now()
+ created_time = datetime.now(timezone.utc)
self._created_time = created_time
self._started_time = None
self._done_time = None
@@ -36,7 +37,7 @@ def keep_in_memory(self):
if self._done_time is None:
return True
- now = datetime.datetime.now()
+ now = datetime.now(timezone.utc)
delta = now - self._done_time
return delta.days < self.keep_in_memory_days
@@ -82,12 +83,12 @@ def set_worker(self, worker):
worker.set_current_job(self)
def set_started(self):
- self._started_time = datetime.datetime.now()
+ self._started_time = datetime.now(timezone.utc)
self._started = True
def set_done(self, success=True, message=None, data=None):
self._done = True
- self._done_time = datetime.datetime.now()
+ self._done_time = datetime.now(timezone.utc)
self._errored = not success
self._message = message
self._result_data = data
@@ -130,7 +131,7 @@ class JobQueue:
old_jobs_check_minutes_interval = 30
def __init__(self):
- self._last_old_jobs_check = datetime.datetime.now()
+ self._last_old_jobs_check = datetime.now(timezone.utc)
self._jobs_by_id = {}
self._job_queue_by_host_name = collections.defaultdict(
collections.deque
@@ -214,7 +215,7 @@ def create_job(self, host_name, job_data):
def _remove_old_jobs(self):
"""Once in specific time look if should remove old finished jobs."""
- delta = datetime.datetime.now() - self._last_old_jobs_check
+ delta = datetime.now(timezone.utc) - self._last_old_jobs_check
if delta.seconds < self.old_jobs_check_minutes_interval:
return
diff --git a/src/quadpype/modules/job_queue/job_workers/base_worker.py b/src/quadpype/modules/job_queue/job_workers/base_worker.py
index 85506565f4..0f8fa292f7 100644
--- a/src/quadpype/modules/job_queue/job_workers/base_worker.py
+++ b/src/quadpype/modules/job_queue/job_workers/base_worker.py
@@ -1,8 +1,9 @@
import sys
-import datetime
import asyncio
import traceback
+from datetime import datetime, timezone
+
from aiohttp_json_rpc import JsonRpcClient
@@ -94,9 +95,9 @@ async def main_loop(self, register_worker=True):
self._is_running = True
while not self._stopped:
- start_time = datetime.datetime.now()
+ start_time = datetime.now(timezone.utc)
await self._connection_loop(register_worker)
- delta = datetime.datetime.now() - start_time
+ delta = datetime.now(timezone.utc) - start_time
print("Connection loop took {}s".format(str(delta)))
# Check if was stopped and stop while loop in that case
if self._stopped:
diff --git a/src/quadpype/modules/slack/plugins/publish/integrate_slack_api.py b/src/quadpype/modules/slack/plugins/publish/integrate_slack_api.py
index 69786d3430..cf0c342ca6 100644
--- a/src/quadpype/modules/slack/plugins/publish/integrate_slack_api.py
+++ b/src/quadpype/modules/slack/plugins/publish/integrate_slack_api.py
@@ -2,7 +2,7 @@
import re
import pyblish.api
import copy
-from datetime import datetime
+from datetime import datetime, timezone
from abc import ABC, abstractmethod
import time
@@ -82,7 +82,7 @@ def process(self, instance):
"msg_id": msg_id,
"file_ids": file_ids,
"project": project,
- "created_dt": datetime.now()
+ "created_dt": datetime.now(timezone.utc)
}
mongo_client = QuadPypeMongoConnection.get_mongo_client()
database_name = os.environ["QUADPYPE_DATABASE_NAME"]
diff --git a/src/quadpype/modules/sync_server/sync_server_module.py b/src/quadpype/modules/sync_server/sync_server_module.py
index 9020bab672..fd3eb0b983 100644
--- a/src/quadpype/modules/sync_server/sync_server_module.py
+++ b/src/quadpype/modules/sync_server/sync_server_module.py
@@ -1,10 +1,11 @@
import os
import sys
import time
-from datetime import datetime
import threading
import copy
import signal
+
+from datetime import datetime, timezone
from collections import deque, defaultdict
from bson.objectid import ObjectId
@@ -303,7 +304,7 @@ def compute_resource_sync_sites(self, project_name):
[
{
'name': '42abbc09-d62a-44a4-815c-a12cd679d2d7',
- 'created_dt': datetime.datetime(2022, 3, 30, 12, 16, 9, 778637)
+ 'created_dt': datetime(2022, 3, 30, 12, 16, 9, 778637)
},
{'name': 'studio'},
{'name': 'SFTP'}
@@ -316,7 +317,7 @@ def create_metadata(name, created=True):
"""Create sync site metadata for site with `name`"""
metadata = {"name": name}
if created:
- metadata["created_dt"] = datetime.now()
+ metadata["created_dt"] = datetime.now(timezone.utc)
return metadata
if (
@@ -528,7 +529,7 @@ def validate_project(self, project_name, site_name, reset_missing=False):
repre_id))
created_dt = datetime.fromtimestamp(
- os.path.getmtime(local_file_path))
+ os.path.getmtime(local_file_path), tz=timezone.utc)
elem = {"name": site_name,
"created_dt": created_dt}
self._add_site(project_name, repre, elem,
@@ -1275,7 +1276,7 @@ def handle_alternate_site(self, project_name, representation,
for alt_site in alternate_sites:
elem = {"name": alt_site,
- "created_dt": datetime.now(),
+ "created_dt": datetime.now(timezone.utc),
"id": synced_file_id}
self.log.debug("Adding alternate {} to {}".format(
@@ -2308,7 +2309,7 @@ def _get_success_dict(self, new_file_id):
(dictionary)
"""
val = {"files.$[f].sites.$[s].id": new_file_id,
- "files.$[f].sites.$[s].created_dt": datetime.now()}
+ "files.$[f].sites.$[s].created_dt": datetime.now(timezone.utc)}
return val
def _get_error_dict(self, error="", tries="", progress=""):
@@ -2321,7 +2322,7 @@ def _get_error_dict(self, error="", tries="", progress=""):
Returns:
(dictionary)
"""
- val = {"files.$[f].sites.$[s].last_failed_dt": datetime.now(),
+ val = {"files.$[f].sites.$[s].last_failed_dt": datetime.now(timezone.utc),
"files.$[f].sites.$[s].error": error,
"files.$[f].sites.$[s].tries": tries,
"files.$[f].sites.$[s].progress": progress
diff --git a/src/quadpype/modules/sync_server/tray/models.py b/src/quadpype/modules/sync_server/tray/models.py
index b251ab8ff4..0f61fa0b77 100644
--- a/src/quadpype/modules/sync_server/tray/models.py
+++ b/src/quadpype/modules/sync_server/tray/models.py
@@ -1,8 +1,9 @@
import os
+
+from datetime import datetime, timezone
+
import attr
from bson.objectid import ObjectId
-import datetime
-
from qtpy import QtCore
import qtawesome
@@ -577,7 +578,7 @@ def add_page_records(self, local_site, remote_site, representations):
remote_provider = lib.translate_provider_for_icon(self.sync_server,
self.project,
remote_site)
- current_date = datetime.datetime.now()
+ current_date = datetime.now(timezone.utc)
for repre in result.get("paginatedResults"):
files = repre.get("files", [])
if isinstance(files, dict): # aggregate returns dictionary
@@ -659,7 +660,7 @@ def get_query(self, limit=0):
limit = SyncRepresentationSummaryModel.PAGE_SIZE
# replace null with value in the future for better sorting
- dummy_max_date = datetime.datetime(2099, 1, 1)
+ dummy_max_date = datetime(2099, 1, 1, tzinfo=timezone.utc)
aggr = [
{"$match": self.get_match_part()},
{'$unwind': '$files'},
@@ -1053,7 +1054,7 @@ def add_page_records(self, local_site, remote_site, representations):
self.project,
remote_site)
- current_date = datetime.datetime.now()
+ current_date = datetime.now(timezone.utc)
for repre in result.get("paginatedResults"):
# log.info("!!! repre:: {}".format(repre))
files = repre.get("files", [])
@@ -1115,7 +1116,7 @@ def get_query(self, limit=0):
if limit == 0:
limit = SyncRepresentationSummaryModel.PAGE_SIZE
- dummy_max_date = datetime.datetime(2099, 1, 1)
+ dummy_max_date = datetime(2099, 1, 1, tzinfo=timezone.utc)
aggr = [
{"$match": self.get_match_part()},
{"$unwind": "$files"},
diff --git a/src/quadpype/modules/update_zxp_extensions_action.py b/src/quadpype/modules/update_zxp_extensions_action.py
deleted file mode 100644
index a5e11673fa..0000000000
--- a/src/quadpype/modules/update_zxp_extensions_action.py
+++ /dev/null
@@ -1,38 +0,0 @@
-import os
-
-from quadpype.modules import QuadPypeModule, ITrayAction
-from quadpype.settings import get_global_settings
-from quadpype.lib.version import get_package
-
-import igniter
-from igniter.zxp_utils import get_zxp_extensions_to_update
-
-
-class UpdateZXPExtensionsAction(QuadPypeModule, ITrayAction):
- name = "update_zxp_extensions"
- label = "Update ZXP Extensions"
- submenu = "More Tools"
-
- def __init__(self, manager, settings):
- super().__init__(manager, settings)
-
- def initialize(self, _modules_settings):
- self.enabled = True
- if os.getenv("QUADPYPE_IGNORE_ZXP_UPDATE"):
- self.enabled = False
-
- def tray_init(self):
- return
-
- def tray_start(self):
- return
-
- def tray_exit(self):
- return
-
- def on_action_trigger(self):
- quadpype_version = get_package("quadpype").running_version
-
- global_settings = get_global_settings()
- zxp_hosts_to_update = get_zxp_extensions_to_update(quadpype_version.path, global_settings, force=True)
- igniter.open_zxp_update_window(quadpype_version.path, zxp_hosts_to_update)
diff --git a/src/quadpype/plugins/publish/extract_otio_review.py b/src/quadpype/plugins/publish/extract_otio_review.py
index d11fbfad5e..dd6a06c792 100644
--- a/src/quadpype/plugins/publish/extract_otio_review.py
+++ b/src/quadpype/plugins/publish/extract_otio_review.py
@@ -70,6 +70,10 @@ def process(self, instance):
handle_end = instance.data["handleEnd"]
otio_review_clips = instance.data["otioReviewClips"]
+ if otio_review_clips is None:
+ self.log.info(f"Instance `{instance}` has no otioReviewClips")
+ return
+
# add plugin wide attributes
self.representation_files = list()
self.used_frames = list()
@@ -85,8 +89,7 @@ def process(self, instance):
# skip instance if no reviewable data available
if (not isinstance(otio_review_clips[0], otio.schema.Clip)) \
and (len(otio_review_clips) == 1):
- self.log.warning(
- "Instance `{}` has nothing to process".format(instance))
+ self.log.warning(f"Instance `{instance}` has nothing to process")
return
else:
self.staging_dir = self.staging_dir(instance)
diff --git a/src/quadpype/plugins/publish/integrate.py b/src/quadpype/plugins/publish/integrate.py
index f6230a3096..bbfd2b74e5 100644
--- a/src/quadpype/plugins/publish/integrate.py
+++ b/src/quadpype/plugins/publish/integrate.py
@@ -1,7 +1,8 @@
import os
import logging
import copy
-import datetime
+
+from datetime import datetime, timezone
import clique
from bson.objectid import ObjectId
@@ -328,7 +329,7 @@ def register(self, instance, file_transactions, filtered_repres):
if sync_server_module is None:
sites = [{
"name": "studio",
- "created_dt": datetime.datetime.now()
+ "created_dt": datetime.now(timezone.utc)
}]
else:
sites = sync_server_module.compute_resource_sync_sites(
diff --git a/src/quadpype/settings/handlers.py b/src/quadpype/settings/handlers.py
index fc4ff5c70b..43ed72fc3a 100644
--- a/src/quadpype/settings/handlers.py
+++ b/src/quadpype/settings/handlers.py
@@ -1,8 +1,9 @@
import os
import copy
import collections
-import datetime
import platform
+
+from datetime import datetime, timezone
from abc import ABC, abstractmethod
import quadpype.version
@@ -69,7 +70,7 @@ def __init__(
timestamp_obj = None
if timestamp:
- timestamp_obj = datetime.datetime.strptime(
+ timestamp_obj = datetime.strptime(
timestamp, self.timestamp_format
)
self.timestamp = timestamp
@@ -91,7 +92,7 @@ def create_new(
from quadpype.lib import get_user_workstation_info
- now = datetime.datetime.now()
+ now = datetime.now(timezone.utc)
workstation_info = get_user_workstation_info()
return cls(
@@ -804,7 +805,7 @@ def save_change_log(self, project_name, changes, settings_type):
"workstation_name": host_info["workstation_name"],
"host_ip": host_info["host_ip"],
"system_name": host_info["system_name"],
- "date_created": datetime.datetime.now(),
+ "date_created": datetime.now(timezone.utc),
"project": project_name,
"settings_type": settings_type,
"changes": changes
diff --git a/src/quadpype/tests/mongo_performance.py b/src/quadpype/tests/mongo_performance.py
index 7e3516651c..89cf9563d4 100644
--- a/src/quadpype/tests/mongo_performance.py
+++ b/src/quadpype/tests/mongo_performance.py
@@ -1,7 +1,7 @@
import pymongo
import bson
import random
-from datetime import datetime
+from datetime import datetime, timezone
import os
@@ -267,7 +267,7 @@ def get_sites(self, number_of_sites=50):
site = {'name': "local_{}".format(i)}
# do not create null 'created_dt' field, Mongo doesnt like it
if i == 0:
- site['created_dt'] = datetime.now()
+ site['created_dt'] = datetime.now(timezone.utc)
sites.append(site)
diff --git a/src/quadpype/tools/loader/widgets.py b/src/quadpype/tools/loader/widgets.py
index 884c3bd67c..ca58a891cc 100644
--- a/src/quadpype/tools/loader/widgets.py
+++ b/src/quadpype/tools/loader/widgets.py
@@ -1,10 +1,10 @@
import os
import sys
-import datetime
import pprint
import traceback
import collections
+from datetime import datetime
from qtpy import QtWidgets, QtCore, QtGui
from quadpype.client import (
@@ -716,8 +716,14 @@ def set_version(self, version_doc=None, version_id=None):
# Define readable creation timestamp
created = version_doc["data"]["time"]
- created = datetime.datetime.strptime(created, "%Y%m%dT%H%M%SZ")
- created = datetime.datetime.strftime(created, "%b %d %Y %H:%M")
+ try:
+ # Retro-compatibility, for published elements before version 4.0.13
+ created = datetime.strptime(created, "%Y%m%dT%H%M%SZ")
+ except ValueError:
+ created = datetime.fromisoformat(created)
+
+ created = created.astimezone()
+ created = datetime.strftime(created, "%b %d %Y %H:%M")
comment = version_doc["data"].get("comment", None) or "No comment"
@@ -747,7 +753,7 @@ def set_version(self, version_doc=None, version_id=None):
"Comment
"
"{comment}
"
- "Created
"
+ "Created (in local timezone)
"
"{created}
"
"Source
"
diff --git a/src/quadpype/tools/push_to_project/control_integrate.py b/src/quadpype/tools/push_to_project/control_integrate.py
index c5ce4f49ae..759f774c08 100644
--- a/src/quadpype/tools/push_to_project/control_integrate.py
+++ b/src/quadpype/tools/push_to_project/control_integrate.py
@@ -3,10 +3,11 @@
import copy
import socket
import itertools
-import datetime
import sys
import traceback
+from datetime import datetime, timezone
+
from bson.objectid import ObjectId
from quadpype.client import (
@@ -1114,7 +1115,7 @@ def _prepare_database_operations(
if sync_server_module is None or not sync_server_module.enabled:
sites = [{
"name": "studio",
- "created_dt": datetime.datetime.now()
+ "created_dt": datetime.now(timezone.utc)
}]
else:
sites = sync_server_module.compute_resource_sync_sites(
diff --git a/src/quadpype/tools/settings/settings/base.py b/src/quadpype/tools/settings/settings/base.py
index 35b18150c1..29f87a3ede 100644
--- a/src/quadpype/tools/settings/settings/base.py
+++ b/src/quadpype/tools/settings/settings/base.py
@@ -3,8 +3,8 @@
import json
import traceback
import functools
-import datetime
+from datetime import datetime, timezone
from abc import abstractmethod
from qtpy import QtWidgets, QtGui, QtCore
@@ -64,7 +64,7 @@ def ask_for_save_filepath(cls, parent):
@classmethod
def extract_settings_to_json(cls, filepath, settings_data, project_name):
- now = datetime.datetime.now()
+ now = datetime.now(timezone.utc)
settings_data[SAVE_TIME_KEY] = now.strftime("%Y-%m-%d %H:%M:%S")
if project_name != 0:
settings_data[PROJECT_NAME_KEY] = project_name
diff --git a/src/quadpype/tools/stdout_broker/app.py b/src/quadpype/tools/stdout_broker/app.py
index 502f95ef9c..c513147f43 100644
--- a/src/quadpype/tools/stdout_broker/app.py
+++ b/src/quadpype/tools/stdout_broker/app.py
@@ -4,7 +4,7 @@
import collections
import websocket
import json
-from datetime import datetime
+from datetime import datetime, timezone
from quadpype.lib import Logger
from quadpype_modules.webserver.host_console_listener import MsgAction
@@ -28,7 +28,7 @@ def __init__(self, host_name):
self.original_stderr_write = None
self.log_queue = collections.deque()
- date_str = datetime.now().strftime("%d%m%Y%H%M%S")
+ date_str = datetime.now(timezone.utc).strftime("%d%m%Y%H%M%S")
self.host_id = "{}_{}".format(self.host_name, date_str)
self._std_available = False
diff --git a/src/quadpype/tools/utils/delegates.py b/src/quadpype/tools/utils/delegates.py
index 10167a3f60..ef302de614 100644
--- a/src/quadpype/tools/utils/delegates.py
+++ b/src/quadpype/tools/utils/delegates.py
@@ -1,5 +1,4 @@
-import time
-from datetime import datetime
+from datetime import datetime, timezone
import logging
import numbers
@@ -219,7 +218,7 @@ def pretty_date(t, now=None, strftime="%b %d %Y %H:%M"):
assert isinstance(t, datetime)
if now is None:
- now = datetime.now()
+ now = datetime.now(timezone.utc)
assert isinstance(now, datetime)
diff = now - t
@@ -245,6 +244,8 @@ def pretty_date(t, now=None, strftime="%b %d %Y %H:%M"):
hours = second_diff // 3600
return "{0}:{1:02d} hours ago".format(hours, minutes)
+ t = t.astimezone()
+
return t.strftime(strftime)
@@ -268,23 +269,29 @@ def pretty_timestamp(t, now=None):
if now is not None:
try:
- now = time.strptime(now, "%Y%m%dT%H%M%SZ")
- now = datetime.fromtimestamp(time.mktime(now))
- except ValueError as e:
- log.warning("Can't parse 'now' time format: {0} {1}".format(t, e))
- return None
+ # Retro-compatibility, for published elements before version 4.0.13
+ now = datetime.strptime(now, "%Y%m%dT%H%M%SZ")
+ except ValueError:
+ try:
+ now = datetime.fromisoformat(now)
+ except ValueError as e:
+ log.warning("Can't parse 'now' time format: {0} {1}".format(t, e))
+ return None
if isinstance(t, float):
- dt = datetime.fromtimestamp(t)
+ dt = datetime.fromtimestamp(t, tz=timezone.utc)
else:
# Parse the time format as if it is `str` result from
- # `pyblish.lib.time()` which usually is stored in Avalon database.
+ # `pyblish.lib.time()` which usually is stored in QuadPype database.
try:
- t = time.strptime(t, "%Y%m%dT%H%M%SZ")
- except ValueError as e:
- log.warning("Can't parse time format: {0} {1}".format(t, e))
- return None
- dt = datetime.fromtimestamp(time.mktime(t))
+ # Retro-compatibility, for published elements before version 4.0.13
+ dt = datetime.strptime(t, "%Y%m%dT%H%M%SZ")
+ except ValueError:
+ try:
+ dt = datetime.fromisoformat(t)
+ except ValueError as e:
+ log.warning("Can't parse time format: {0} {1}".format(t, e))
+ return None
# prettify
return pretty_date(dt, now=now)
diff --git a/src/quadpype/tools/workfiles/window.py b/src/quadpype/tools/workfiles/window.py
index e04e043600..14ac859239 100644
--- a/src/quadpype/tools/workfiles/window.py
+++ b/src/quadpype/tools/workfiles/window.py
@@ -1,7 +1,9 @@
import os
-import datetime
import copy
import platform
+
+from datetime import datetime
+
from qtpy import QtCore, QtWidgets, QtGui
from quadpype.client import (
@@ -144,8 +146,8 @@ def set_context(self, asset_id, task_name, filepath, workfile_doc):
# Append html string
datetime_format = "%b %d %Y %H:%M:%S"
- creation_time = datetime.datetime.fromtimestamp(filestat.st_ctime)
- modification_time = datetime.datetime.fromtimestamp(filestat.st_mtime)
+ creation_time = datetime.fromtimestamp(filestat.st_ctime)
+ modification_time = datetime.fromtimestamp(filestat.st_mtime)
lines = (
"Size:",
size_value,
diff --git a/src/start.py b/src/start.py
index 998572d1a8..8c279d4a7c 100644
--- a/src/start.py
+++ b/src/start.py
@@ -184,12 +184,6 @@ def _print(msg: str, force=False):
ssl_cert_file = certifi.where()
os.environ["SSL_CERT_FILE"] = ssl_cert_file
-if "--zxp-ignore-update" in sys.argv:
- os.environ["QUADPYPE_IGNORE_ZXP_UPDATE"] = "1"
- sys.argv.remove("--zxp-ignore-update")
-elif os.getenv("QUADPYPE_IGNORE_ZXP_UPDATE") != "1":
- os.environ.pop("QUADPYPE_IGNORE_ZXP_UPDATE", None)
-
if "--headless" in sys.argv:
os.environ["QUADPYPE_HEADLESS_MODE"] = "1"
sys.argv.remove("--headless")
@@ -939,9 +933,8 @@ def boot():
running_version = package_manager["quadpype"].running_version
running_version_fullpath = running_version.path.resolve()
- if not os.getenv("QUADPYPE_IGNORE_ZXP_UPDATE"):
- _print(">>> Check ZXP extensions ...")
- _update_zxp_extensions(running_version_fullpath, global_settings)
+ _print(">>> Check ZXP extensions ...")
+ _update_zxp_extensions(running_version_fullpath, global_settings)
# print info when not running scripts defined in 'silent commands'
if all(arg not in silent_commands for arg in sys.argv):