mirror of
https://github.com/fergalmoran/picard.git
synced 2026-01-06 08:34:01 +00:00
Add $datetime() function and associated tests
This commit is contained in:
committed by
Philipp Wolfer
parent
f090c06572
commit
7762f9b929
@@ -21,6 +21,7 @@
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
from collections import namedtuple
|
||||
import datetime
|
||||
from functools import reduce
|
||||
from inspect import getfullargspec
|
||||
import operator
|
||||
@@ -1201,3 +1202,28 @@ def func_slice(parser, multi, start_index, end_index, separator=MULTI_VALUED_JOI
|
||||
return separator.join(multi_var[start:end])
|
||||
except IndexError:
|
||||
return ''
|
||||
|
||||
|
||||
@script_function()
|
||||
def func_datetime(parser, format=None):
|
||||
"""Return the current date and time as a string.
|
||||
|
||||
Arguments:
|
||||
parser: The ScriptParser object used to parse the script.
|
||||
format: A string or the ScriptVariable/Function that evaluates to the
|
||||
string used to format the output. Default is '%Y-%m-%d %H:%M:%S'
|
||||
if blank. Uses strftime() format.
|
||||
|
||||
Returns:
|
||||
Returns the current date and time as a string.
|
||||
"""
|
||||
# local_tz required for Python 3.5 which does not allow setting astimezone()
|
||||
# on a naive datetime.datetime object. This provides timezone information to
|
||||
# allow the use of %Z and %z in the output format.
|
||||
local_tz = datetime.datetime.now(datetime.timezone.utc).astimezone().tzinfo
|
||||
|
||||
# Handle case where format evaluates to ''
|
||||
if not format:
|
||||
format = '%Y-%m-%d %H:%M:%S'
|
||||
|
||||
return datetime.datetime.now(tz=local_tz).strftime(format)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import datetime
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from test.picardtestcase import PicardTestCase
|
||||
@@ -16,6 +17,38 @@ from picard.script import (
|
||||
)
|
||||
|
||||
|
||||
class _TestTimezone(datetime.tzinfo):
|
||||
def utcoffset(self, dt):
|
||||
# Set to GMT+2
|
||||
return datetime.timedelta(hours=2) + self.dst(dt)
|
||||
|
||||
def dst(self, dt):
|
||||
d = datetime.datetime(dt.year, 4, 1)
|
||||
self.dston = d - datetime.timedelta(days=d.weekday() + 1)
|
||||
d = datetime.datetime(dt.year, 11, 1)
|
||||
self.dstoff = d - datetime.timedelta(days=d.weekday() + 1)
|
||||
if self.dston <= dt.replace(tzinfo=None) < self.dstoff:
|
||||
return datetime.timedelta(hours=1)
|
||||
else:
|
||||
return datetime.timedelta(0)
|
||||
|
||||
def tzname(self,dt):
|
||||
return "TZ Test"
|
||||
|
||||
|
||||
class _DateTime(datetime.datetime):
|
||||
@classmethod
|
||||
def now(cls, tz=None):
|
||||
return datetime.datetime(2020, 1, 2, hour=12, minute=34, second=56, microsecond=789, tzinfo=tz)
|
||||
|
||||
def astimezone(self, tz=None):
|
||||
# Ignore tz passed to the method and force use of test timezone.
|
||||
tz = _TestTimezone()
|
||||
utc = (self - self.utcoffset()).replace(tzinfo=tz)
|
||||
# Convert from UTC to tz's local time.
|
||||
return tz.fromutc(utc)
|
||||
|
||||
|
||||
class ScriptParserTest(PicardTestCase):
|
||||
|
||||
def setUp(self):
|
||||
@@ -943,3 +976,33 @@ class ScriptParserTest(PicardTestCase):
|
||||
self.parser.eval("$slice(abc; def,0)")
|
||||
with self.assertRaisesRegex(ScriptError, areg):
|
||||
self.parser.eval("$slice(abc; def),0,1,:,extra")
|
||||
|
||||
def test_cmd_datetime(self):
|
||||
# Save origninal datetime object and substitute one returning
|
||||
# a fixed now() value for testing.
|
||||
original_datetime = datetime.datetime
|
||||
datetime.datetime = _DateTime
|
||||
|
||||
try:
|
||||
context = Metadata()
|
||||
context["foo"] = "%Y%m%d%H%M%S.%f"
|
||||
# Tests with context
|
||||
self.assertScriptResultEquals("$datetime(%foo%)", "20200102123456.000789", context)
|
||||
self.assertScriptResultEquals("$datetime($initials())", "2020-01-02 12:34:56", context)
|
||||
# Tests with static input
|
||||
self.assertScriptResultEquals("$datetime(\%Y\%m\%d\%H\%M\%S.\%f)", "20200102123456.000789", context)
|
||||
# Tests with timezones
|
||||
self.assertScriptResultEquals("$datetime(\%H\%M\%S \%z \%Z)", "123456 +0200 TZ Test", context)
|
||||
# Tests with missing input
|
||||
self.assertScriptResultEquals("$datetime()", "2020-01-02 12:34:56", context)
|
||||
# Tests with invalid format
|
||||
self.assertScriptResultEquals("$datetime(xxx)", "xxx", context)
|
||||
# Tests with invalid number of arguments
|
||||
areg = r"^Wrong number of arguments for \$datetime: Expected between 0 and 1, "
|
||||
with self.assertRaisesRegex(ScriptError, areg):
|
||||
self.parser.eval("$datetime(abc,def)")
|
||||
except (AssertionError, ValueError, IndexError) as err:
|
||||
raise err
|
||||
finally:
|
||||
# Restore origninal datetime object
|
||||
datetime.datetime = original_datetime
|
||||
|
||||
Reference in New Issue
Block a user