Addon Manager: refactor process_string_to_datetime (#18492)

* Addon Manager: Refactor utilities tests to remove filesystem use

* Addon Manager: Move process_date_string_to_python_datetime to utilities

Also add unit tests and modify the exception type

* Addon Manager: Add tests for other date separators

* Addon Manager: Refactor to reduce duplication

* Addon Manager: add explanation of why the function exists

* Addon Manager: use exception chaining

* Addon Manager: Remove unused test files
This commit is contained in:
Chris Hennes
2024-12-23 12:01:02 -05:00
committed by GitHub
parent b7cae54666
commit 9ef57818be
6 changed files with 115 additions and 130 deletions

View File

@@ -24,8 +24,12 @@
""" Utilities to work across different platforms, providers and python versions """
from datetime import datetime
from typing import Optional, Any
import ctypes
import os
import platform
import re
import shutil
import stat
import subprocess
@@ -443,6 +447,37 @@ def run_interruptable_subprocess(args, timeout_secs: int = 10) -> subprocess.Com
return subprocess.CompletedProcess(args, return_code, stdout, stderr)
def process_date_string_to_python_datetime(date_string: str) -> datetime:
"""For modern macros the expected date format is ISO 8601, YYYY-MM-DD. For older macros this standard was not always
used, and various orderings and separators were used. This function tries to match the majority of those older
macros. Commonly-used separators are periods, slashes, and dashes."""
def raise_error(bad_string: str, root_cause: Exception = None):
raise ValueError(
f"Unrecognized date string '{bad_string}' (expected YYYY-MM-DD)"
) from root_cause
split_result = re.split(r"[ ./-]+", date_string.strip())
if len(split_result) != 3:
raise_error(date_string)
try:
split_result = [int(x) for x in split_result]
# The earliest possible year an addon can be created or edited is 2001:
if split_result[0] > 2000:
return datetime(split_result[0], split_result[1], split_result[2])
elif split_result[2] > 2000:
# Generally speaking it's not possible to distinguish between DD-MM and MM-DD, so try the first, and
# only if that fails try the second
if split_result[1] <= 12:
return datetime(split_result[2], split_result[1], split_result[0])
return datetime(split_result[2], split_result[0], split_result[1])
else:
raise ValueError(f"Invalid year in date string '{date_string}'")
except ValueError as exception:
raise_error(date_string, exception)
def get_main_am_window():
windows = QtWidgets.QApplication.topLevelWidgets()
for widget in windows: