Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Dpkg Time Machine
#!/usr/bin/env python
# file: dpkg-since.py
# description: lists installed packages since the specified date
# changelog:
# * Feb 10 2015 - init release
# * Mar 24 2015 - new: packages sorted by installation time/date
# fix: ignored TIME argument
# * Apr 9 2015 - fix: exclude duplicates
# * Apr 27 2015 - new: recognize dates like '1 hour ago', 'yesterday'
# requires 'dateparser', install with 'pip install dateparser'
# - new: use new line or other splitter character
import sys
import getopt
from os.path import basename
from datetime import datetime
from dateparser.date import DateDataParser
from glob import glob
import gzip
def uniquify(seq):
seen = set()
seen_add = seen.add
return [x for x in seq if x not in seen and not seen_add(x)]
def print_usage():
basename_ = basename(sys.argv[0])
print ''
print 'Usage:\n\t' + basename_ + ' [OPTIONS] DATE'
print ''
print 'Options:'
print '\t-p, --print-date - prints the recognized date as the last line'
print "\t-n, --new-line - use new line as a splitter character"
print "\t-s, --splitter 'char' - set a custom splitter character"
print '\t-h, --help - display this help and exit'
print ''
print 'Examples:'
print '\t' + basename_ + ' -v yesterday'
print '\t' + basename_ + ' -n 1 week ago'
print '\t' + basename_ + " -s ', ' 2015-02-14 16:40:35"
def main():
verbose = False
splitter = " "
try:
opts, args = getopt.getopt(sys.argv[1:], "hps:n", ["help", "print-date", "splitter=", "new-line"])
except getopt.GetoptError as err:
print str(err)
print_usage()
sys.exit(2)
for o, a in opts:
if o in ("-h", "--help"):
print_usage()
sys.exit()
elif o in ("-p", "--print-date"):
verbose = True
elif o in ("-s", "--splitter"):
splitter = a
if splitter == "\\n":
splitter = "\n"
elif o in ("-n", "--new-line"):
splitter = "\n"
else:
assert False, "unhandled option"
if (not args):
print 'missing date arguments'
print_usage()
sys.exit(1)
ddp = DateDataParser()
since_date = ddp.get_date_data(' '.join(args))['date_obj']
packages = []
for log in sorted(glob('/var/log/dpkg.log*'), reverse=True):
if log.endswith('.gz'):
f = gzip.open(log, 'r')
else:
f = open(log, 'r')
for line in f:
cols = line.split()
# date + time columns
line_date = datetime.strptime(cols[0] + ' ' + cols[1], "%Y-%m-%d %H:%M:%S")
if line_date >= since_date:
# keep only installed ones
if cols[2] == 'install':
packages.append(cols[3])
print splitter.join(uniquify(packages))
if verbose:
print "\n" + since_date.ctime() + ""
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment