Skip to content

Instantly share code, notes, and snippets.

@juzam
Forked from gsong/tm-last-backup.py
Last active December 31, 2015 16:09
Show Gist options
  • Save juzam/8011903 to your computer and use it in GitHub Desktop.
Save juzam/8011903 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
from datetime import timedelta, tzinfo
from dateutil import tz
from shlex import split
from subprocess import Popen, PIPE
import os
import plistlib
NOT_ENABLED = u'Not enabled.'
TM_PREFS_PATH = '/Library/Preferences/com.apple.TimeMachine.plist'
TM_RESULTS_PATH = '/private/var/db/.TimeMachine.Results.plist'
# To/From time zones
from_zone = tz.tzutc()
to_zone = tz.tzlocal()
def render_timestamp(dt):
# Simplified TimeZone Conversion
dt = dt.replace(tzinfo=from_zone)
dt = dt.astimezone(to_zone)
return dt.strftime('%Y-%m-%d %H:%M:%S %z')
def popen(command):
return Popen(split(command), stdout=PIPE).stdout.read()
def parse_plist(plist_path):
cmd = '/usr/bin/plutil -convert xml1 -o - "%s"' % plist_path
xml_plist = popen(cmd)
return plistlib.readPlistFromString(xml_plist)
def get_prefs_version(prefs):
return prefs.get('PreferencesVersion', -1)
def pre_version2_result(results):
result = NOT_ENABLED
if os.path.isfile(results):
tm_status = parse_plist(results)
if tm_status.get('BACKUP_COMPLETED_DATE'):
result = render_timestamp(tm_status['BACKUP_COMPLETED_DATE'])
return result
def get_tm_result(prefs, tm_pref_handler):
result = NOT_ENABLED
if tm_pref_handler(prefs):
result = render_timestamp(max(tm_pref_handler(prefs)))
return result
def v2_parser(tm_status):
snapshot_timestamps = []
for d in tm_status['Destinations']:
completed = d.get('BACKUP_COMPLETED_DATE')
if completed:
snapshot_timestamps.append(completed)
return snapshot_timestamps
def v3_parser(tm_status):
snapshot_timestamps = []
for d in tm_status['Destinations']:
snapshot_timestamps.extend(d.get('SnapshotDates', []))
return snapshot_timestamps
def get_tm_status(prefs, results=TM_RESULTS_PATH):
# If the preferences plist doesn't even exist
if not os.path.isfile(prefs):
return u"<result>%s</result>" % NOT_ENABLED
prefs = parse_plist(prefs)
version = int(get_prefs_version(prefs))
# If AutoBackup doesn't exist or isn't enabled
if not int(prefs.get('AutoBackup', 0)):
return u"<result>%s</result>" % NOT_ENABLED
if version == 3:
last_backup = get_tm_result(prefs, v3_parser)
elif version == 2:
last_backup = get_tm_result(prefs, v2_parser)
else:
last_backup = pre_version2_result(results)
return u"%s" % last_backup
if __name__ == '__main__':
print get_tm_status(TM_PREFS_PATH)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment