mirror of
https://github.com/mikf/gallery-dl.git
synced 2024-11-22 18:53:21 +01:00
[formatter] implement 'D' format specifier
To be able to parse any string into a 'datetime' object and format it as necessary. Example: {created_at:D%Y-%m-%dT%H:%M:%S%z} -> "2010-01-01 00:00:00" {created_at:D%Y-%m-%dT%H:%M:%S%z/%b %d %Y %I:%M %p} -> "Jan 01 2010 12:00 AM" with 'created_at' == "2010-01-01T01:00:00+0100"
This commit is contained in:
parent
3a7a19c7b9
commit
3842cdcd8f
@ -160,10 +160,16 @@ Format specifiers can be used for advanced formatting by using the options provi
|
|||||||
<td><code>{foo:Ro/()/}</code></td>
|
<td><code>{foo:Ro/()/}</code></td>
|
||||||
<td><code>F()() Bar</code></td>
|
<td><code>F()() Bar</code></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>D<format>/</code></td>
|
||||||
|
<td>Parse a string value to a <code>datetime</code> object according to <a href="https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes"><code><format></code></a></td>
|
||||||
|
<td><code>{updated:D%b %d %Y %I:%M %p/}</code></td>
|
||||||
|
<td><code>2010-01-01 00:00:00</code></td>
|
||||||
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
All special format specifiers (`?`, `L`, `J`, `R`) can be chained and combined with one another, but must always come before any standard format specifiers:
|
All special format specifiers (`?`, `L`, `J`, `R`, `D`) can be chained and combined with one another, but must always come before any standard format specifiers:
|
||||||
|
|
||||||
For example `{foo:?//RF/B/Ro/e/> 10}` -> ` Bee Bar`
|
For example `{foo:?//RF/B/Ro/e/> 10}` -> ` Bee Bar`
|
||||||
- `?//` - Tests if `foo` has a value
|
- `?//` - Tests if `foo` has a value
|
||||||
|
@ -274,6 +274,8 @@ def build_format_func(format_spec):
|
|||||||
return _parse_join(format_spec)
|
return _parse_join(format_spec)
|
||||||
if fmt == "R":
|
if fmt == "R":
|
||||||
return _parse_replace(format_spec)
|
return _parse_replace(format_spec)
|
||||||
|
if fmt == "D":
|
||||||
|
return _parse_datetime(format_spec)
|
||||||
return _default_format(format_spec)
|
return _default_format(format_spec)
|
||||||
return format
|
return format
|
||||||
|
|
||||||
@ -319,6 +321,16 @@ def _parse_replace(format_spec):
|
|||||||
return replace
|
return replace
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_datetime(format_spec):
|
||||||
|
dt_format, _, format_spec = format_spec.partition("/")
|
||||||
|
dt_format = dt_format[1:]
|
||||||
|
fmt = build_format_func(format_spec)
|
||||||
|
|
||||||
|
def dt(obj):
|
||||||
|
return fmt(text.parse_datetime(obj, dt_format))
|
||||||
|
return dt
|
||||||
|
|
||||||
|
|
||||||
def _default_format(format_spec):
|
def _default_format(format_spec):
|
||||||
def wrap(obj):
|
def wrap(obj):
|
||||||
return format(obj, format_spec)
|
return format(obj, format_spec)
|
||||||
|
@ -29,6 +29,7 @@ class TestFormatter(unittest.TestCase):
|
|||||||
"u": "'< / >'",
|
"u": "'< / >'",
|
||||||
"t": 1262304000,
|
"t": 1262304000,
|
||||||
"dt": datetime.datetime(2010, 1, 1),
|
"dt": datetime.datetime(2010, 1, 1),
|
||||||
|
"ds": "2010-01-01T01:00:00+0100",
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
"title1": "Title",
|
"title1": "Title",
|
||||||
"title2": "",
|
"title2": "",
|
||||||
@ -162,6 +163,11 @@ class TestFormatter(unittest.TestCase):
|
|||||||
self._run_test("{a!l:Rl//}" , "heo word")
|
self._run_test("{a!l:Rl//}" , "heo word")
|
||||||
self._run_test("{name:Rame/othing/}", "Nothing")
|
self._run_test("{name:Rame/othing/}", "Nothing")
|
||||||
|
|
||||||
|
def test_datetime(self):
|
||||||
|
self._run_test("{ds:D%Y-%m-%dT%H:%M:%S%z}", "2010-01-01 00:00:00")
|
||||||
|
self._run_test("{ds:D%Y}", "2010-01-01T01:00:00+0100")
|
||||||
|
self._run_test("{l:D%Y}", "None")
|
||||||
|
|
||||||
def test_chain_special(self):
|
def test_chain_special(self):
|
||||||
# multiple replacements
|
# multiple replacements
|
||||||
self._run_test("{a:Rh/C/RE/e/RL/l/}", "Cello wOrld")
|
self._run_test("{a:Rh/C/RE/e/RL/l/}", "Cello wOrld")
|
||||||
@ -174,6 +180,9 @@ class TestFormatter(unittest.TestCase):
|
|||||||
self._run_test("{d[a]:?</>/L1/too long/}", "<too long>")
|
self._run_test("{d[a]:?</>/L1/too long/}", "<too long>")
|
||||||
self._run_test("{d[c]:?</>/L5/too long/}", "")
|
self._run_test("{d[c]:?</>/L5/too long/}", "")
|
||||||
|
|
||||||
|
# parse and format datetime
|
||||||
|
self._run_test("{ds:D%Y-%m-%dT%H:%M:%S%z/%Y%m%d}", "20100101")
|
||||||
|
|
||||||
def test_globals_env(self):
|
def test_globals_env(self):
|
||||||
os.environ["FORMATTER_TEST"] = value = self.kwdict["a"]
|
os.environ["FORMATTER_TEST"] = value = self.kwdict["a"]
|
||||||
|
|
||||||
@ -259,7 +268,7 @@ def noarg():
|
|||||||
sys.path.pop(0)
|
sys.path.pop(0)
|
||||||
|
|
||||||
self.assertEqual(fmt1.format_map(self.kwdict), "'Title' by Name")
|
self.assertEqual(fmt1.format_map(self.kwdict), "'Title' by Name")
|
||||||
self.assertEqual(fmt2.format_map(self.kwdict), "65")
|
self.assertEqual(fmt2.format_map(self.kwdict), "89")
|
||||||
|
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
self.assertEqual(fmt3.format_map(self.kwdict), "")
|
self.assertEqual(fmt3.format_map(self.kwdict), "")
|
||||||
|
Loading…
Reference in New Issue
Block a user