implement 'mtime' post-processor (#332)

This can set a file's modification time according to a UNIX timestamp
or a datetime object from its metadata.
This commit is contained in:
Mike Fährmann
2019-07-14 22:37:28 +02:00
parent 62097284fe
commit 16c582aaf9
6 changed files with 65 additions and 13 deletions

View File

@@ -1290,6 +1290,23 @@ Description Custom format string to build content of metadata files.
=========== =====
mtime
-----
Set file modification time according to its metadata
mtime.key
---------
=========== =====
Type ``string``
Default ``"date"``
Description Name of the metadata field whose value should be used.
This value must either be a UNIX timestamp or a
|datetime|_ object.
=========== =====
ugoira
------
@@ -1648,6 +1665,7 @@ Description An object with the ``name`` of a post-processor and its options.
.. |verify| replace:: ``verify``
.. |mature_content| replace:: ``mature_content``
.. |webbrowser.open()| replace:: ``webbrowser.open()``
.. |datetime| replace:: ``datetime``
.. |datetime.max| replace:: ``datetime.max``
.. |Path| replace:: ``Path``
.. |Last-Modified| replace:: ``Last-Modified``
@@ -1673,6 +1691,7 @@ Description An object with the ``name`` of a post-processor and its options.
.. _strptime: https://docs.python.org/3/library/datetime.html#strftime-strptime-behavior
.. _mature_content: https://www.deviantart.com/developers/http/v1/20160316/object/deviation
.. _webbrowser.open(): https://docs.python.org/3/library/webbrowser.html
.. _datetime: https://docs.python.org/3/library/datetime.html#datetime-objects
.. _datetime.max: https://docs.python.org/3/library/datetime.html#datetime.datetime.max
.. _Authentication: https://github.com/mikf/gallery-dl#5authentication
.. _youtube-dl: https://github.com/ytdl-org/youtube-dl

View File

@@ -160,9 +160,7 @@ class HttpDownloader(DownloaderBase):
if adj_ext:
pathfmt.set_extension(adj_ext)
if self.mtime:
filetime = response.headers.get("Last-Modified")
if filetime:
pathfmt.keywords["_filetime"] = filetime
pathfmt.keywords["_mtime"] = response.headers.get("Last-Modified")
return True
def receive(self, response, file):

View File

@@ -322,6 +322,12 @@ def build_parser():
action="append_const", const={"name": "metadata", "mode": "tags"},
help="Write image tags to separate text files",
)
postprocessor.add_argument(
"--mtime-from-date",
dest="postprocessors",
action="append_const", const={"name": "mtime"},
help="Set file modification times according to 'date' metadata",
)
parser.add_argument(
"urls",

View File

@@ -15,6 +15,7 @@ modules = [
"classify",
"exec",
"metadata",
"mtime",
"ugoira",
"zip",
]

View File

@@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
# Copyright 2019 Mike Fährmann
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
"""Use metadata as file modification time"""
from .common import PostProcessor
from ..text import parse_int
class MtimePP(PostProcessor):
def __init__(self, pathfmt, options):
PostProcessor.__init__(self)
self.key = options.get("key", "date")
def run(self, pathfmt):
mtime = pathfmt.keywords.get(self.key)
ts = getattr(mtime, "timestamp", None)
pathfmt.keywords["_mtime"] = ts() if ts else parse_int(mtime)
__postprocessor__ = MtimePP

View File

@@ -20,8 +20,8 @@ import sqlite3
import datetime
import operator
import itertools
import email.utils
import urllib.parse
from email.utils import mktime_tz, parsedate_tz
from . import text, exception
@@ -639,15 +639,16 @@ class PathFormat():
shutil.copyfile(self.temppath, self.realpath)
os.unlink(self.temppath)
if "_filetime" in self.keywords:
# try to set file times
try:
filetime = email.utils.mktime_tz(email.utils.parsedate_tz(
self.keywords["_filetime"]))
if filetime:
os.utime(self.realpath, (time.time(), filetime))
except Exception:
pass
if "_mtime" in self.keywords:
# set file modification time
mtime = self.keywords["_mtime"]
if mtime:
try:
if isinstance(mtime, str):
mtime = mktime_tz(parsedate_tz(mtime))
os.utime(self.realpath, (time.time(), mtime))
except Exception:
pass
@staticmethod
def adjust_path(path):