浏览代码

PR #285 - Merge branch 'archive_timestamp' into merge

Thomas Waldmann 10 年之前
父节点
当前提交
310f9b7412
共有 3 个文件被更改,包括 31 次插入4 次删除
  1. 4 2
      attic/archive.py
  2. 7 2
      attic/archiver.py
  3. 20 0
      attic/helpers.py

+ 4 - 2
attic/archive.py

@@ -199,11 +199,13 @@ class Archive:
         del self.manifest.archives[self.checkpoint_name]
         self.cache.chunk_decref(self.id, self.stats)
 
-    def save(self, name=None):
+    def save(self, name=None, timestamp=None):
         name = name or self.name
         if name in self.manifest.archives:
             raise self.AlreadyExists(name)
         self.items_buffer.flush(flush=True)
+        if timestamp is None:
+            timestamp = datetime.utcnow()
         metadata = StableDict({
             'version': 1,
             'name': name,
@@ -211,7 +213,7 @@ class Archive:
             'cmdline': sys.argv,
             'hostname': socket.gethostname(),
             'username': getuser(),
-            'time': datetime.utcnow().isoformat(),
+            'time': timestamp.isoformat(),
         })
         data = msgpack.packb(metadata, unicode_errors='surrogateescape')
         self.id = self.key.id_hash(data)

+ 7 - 2
attic/archiver.py

@@ -15,7 +15,7 @@ from attic.repository import Repository
 from attic.cache import Cache
 from attic.key import key_creator
 from attic.helpers import Error, location_validator, format_time, \
-    format_file_mode, ExcludePattern, exclude_path, adjust_patterns, to_localtime, \
+    format_file_mode, ExcludePattern, exclude_path, adjust_patterns, to_localtime, timestamp, \
     get_cache_dir, get_keys_dir, format_timedelta, prune_within, prune_split, \
     Manifest, remove_surrogates, update_excludes, format_archive, check_extension_modules, Statistics, \
     is_cachedir, bigint_to_int
@@ -135,7 +135,7 @@ Type "Yes I am sure" if you understand this and want to continue.\n""")
             else:
                 restrict_dev = None
             self._process(archive, cache, args.excludes, args.exclude_caches, skip_inodes, path, restrict_dev)
-        archive.save()
+        archive.save(timestamp=args.timestamp)
         if args.progress:
             archive.stats.show_progress(final=True)
         if args.stats:
@@ -612,6 +612,11 @@ Type "Yes I am sure" if you understand this and want to continue.\n""")
         subparser.add_argument('--numeric-owner', dest='numeric_owner',
                                action='store_true', default=False,
                                help='only store numeric user and group identifiers')
+        subparser.add_argument('--timestamp', dest='timestamp',
+                               type=timestamp, default=None,
+                               metavar='yyyy-mm-ddThh:mm:ss',
+                               help='manually specify the archive creation date/time (UTC). '
+                                    'alternatively, give a reference file/directory.')
         subparser.add_argument('archive', metavar='ARCHIVE',
                                type=location_validator(archive=True),
                                help='archive to create')

+ 20 - 0
attic/helpers.py

@@ -269,6 +269,26 @@ class ExcludePattern(IncludePattern):
         return '%s(%s)' % (type(self), self.pattern)
 
 
+def timestamp(s):
+    """Convert a --timestamp=s argument to a datetime object"""
+    try:
+        # is it pointing to a file / directory?
+        ts = os.stat(s).st_mtime
+        return datetime.utcfromtimestamp(ts)
+    except OSError:
+        # didn't work, try parsing as timestamp. UTC, no TZ, no microsecs support.
+        for format in ('%Y-%m-%dT%H:%M:%SZ', '%Y-%m-%dT%H:%M:%S+00:00',
+                       '%Y-%m-%dT%H:%M:%S', '%Y-%m-%d %H:%M:%S',
+                       '%Y-%m-%dT%H:%M', '%Y-%m-%d %H:%M',
+                       '%Y-%m-%d', '%Y-%j',
+                       ):
+            try:
+                return datetime.strptime(s, format)
+            except ValueError:
+                continue
+        raise ValueError
+
+
 def is_cachedir(path):
     """Determines whether the specified path is a cache directory (and
     therefore should potentially be excluded from the backup) according to