Commit 702e75e0 authored by Georgios D. Tsoukalas's avatar Georgios D. Tsoukalas

timeview: cmdline util for backup timeview

parent 75ae4fe6
This diff is collapsed.
This diff is collapsed.
--- dup_time.py.orig 2015-10-26 16:27:59.153178600 +0200
+++ dup_time.py 2015-10-26 16:25:45.625178600 +0200
@@ -28,6 +28,7 @@
import re
import calendar
from duplicity import globals
+from datetime import datetime
class TimeException(Exception):
@@ -155,7 +156,10 @@
def timetopretty(timeinseconds):
"""Return pretty version of time"""
- return time.asctime(time.localtime(timeinseconds))
+
+ isotime = datetime.isoformat(datetime.fromtimestamp(timeinseconds), '.')
+ return isotime
+ #return time.asctime(time.localtime(timeinseconds))
def stringtopretty(timestring):
This diff is collapsed.
This diff is collapsed.
--- duplicity.orig 2015-10-26 16:28:48.053178600 +0200
+++ duplicity 2015-10-26 16:25:34.705178600 +0200
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/w/venv/agkyra/bin/python
# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
#
# duplicity -- Encrypted bandwidth efficient backup
@@ -693,8 +693,9 @@
path_iter = diffdir.get_combined_path_iter(sig_chain.get_fileobjs(time))
for path in path_iter:
if path.difftype != "deleted":
- user_info = u"%s %s" % (dup_time.timetopretty(path.getmtime()),
- util.ufn(path.get_relative_path()))
+ user_info = u"\0%s %s %s\0" % (path.type,
+ dup_time.timetopretty(path.getmtime()),
+ util.ufn(path.get_relative_path()))
log_info = "%s %s %s" % (dup_time.timetostring(path.getmtime()),
util.escape(path.get_relative_path()),
path.type)
from os import listdir, makedirs
from os.path import exists, isdir
from subprocess import Popen, PIPE
import json
import errno
path_types = {'reg', 'dir', 'sym', 'fifo', 'sock', 'chr', 'blk'}
def path_join(*args):
return '/'.join(str(x).strip('/') for x in args)
def timestamp_rfc822_to_iso8601(string):
from email.utils import parsedate
year, month, day, hour, minute, second, _, _, _ = parsedate(string)
return "%04u-%02u-%02uT%02u:%02u:%02u" % (
year, month, day, hour, minute, second)
def print_listing(openfile, root, path=()):
openfile.write(root.get('timestamp', "- -")
+ ' ' + root.get('type', '-')
+ ' ' + '/'.join(path) + '\0\n')
for name, entry in root['entries'].iteritems():
print_listing(openfile, entry, path=path + (name,))
def put_timepoint(config, timepoint, data):
root = {'entries': {}}
lines = data.split('\0')
for i, line in enumerate(lines):
if i & 1 == 0:
continue
line.strip('\n').strip('\0')
if not line:
continue
parts = line.split(' ', 5)
entry_type = parts[0]
if entry_type not in path_types:
continue
timestamp = ' '.join(parts[1:-1])
segments = parts[-1].split('/')
node = root
for segment in segments:
entries = node['entries']
if segment not in entries:
entries[segment] = {'entries': {}}
node = entries[segment]
node['timestamp'] = timestamp
node['type'] = entry_type
datafile = path_join(config['datapath'], timepoint)
with open(datafile, "w") as f:
f.write(json.dumps(root, indent=2))
def fetch_timepoint(config, timepoint):
args = ['duplicity', 'list-current-files', '-t', timepoint,
config['target_url']]
proc = Popen(args, stdout=PIPE, stderr=PIPE)
procout, procerr = proc.communicate()
proc.wait()
if proc.returncode != 0:
raise RuntimeError(procerr)
put_timepoint(config, timepoint, procout)
def get_timepoint(config, timepoint, path):
datafile = path_join(config['datapath'], timepoint)
retries = 1
while True:
try:
with open(datafile) as f:
data = f.read()
break
except IOError as e:
if e.errno != errno.ENOENT or retries == 0:
raise
fetch_timepoint(config, timepoint)
if retries <= 0:
raise e
retries -= 1
node = json.loads(data)
path = path.strip('/').split('/')
for i in xrange(len(path)):
segment = path[i]
if not segment:
continue
entries = node['entries']
if segment not in entries:
return []
node = entries[segment]
return sorted({'name': name,
'type': entry['type'],
'timestamp': entry['timestamp']}
for name, entry in node['entries'].iteritems())
def ensure_datapath(datapath):
if not exists(datapath):
makedirs(datapath)
elif not isdir(datapath):
m = "%r not a directory" % datapath
raise IOError(m)
def get_config():
with open("timeview.config") as f:
data = f.read()
config = literal_eval(data)
datapath = config['datapath']
ensure_datapath(datapath)
return config
def main():
from sys import argv, stdin, stdout
def help():
print "Usage: %s <datapath> <target_url> [get <absolute_timepoint> <path> | list]" % argv[0]
raise SystemExit(1)
if len(argv) < 4:
help()
datapath = argv[1]
ensure_datapath(datapath)
target_url = argv[2]
cmd = argv[3]
if cmd not in ['get', 'list']:
help()
#config = get_config()
config = {'datapath': datapath, 'target_url': target_url}
if cmd == 'get':
if len(argv) < 6:
help()
timepoint = argv[4]
path = argv[5]
r = get_timepoint(config, timepoint, path)
print json.dumps(r, indent=2)
elif cmd == 'list':
print json.dumps(sorted(listdir(config['datapath'])), indent=2)
else:
help()
if __name__ == "__main__":
main()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment