Strike
09-19-2002, 10:37 PM
I whipped up a script that does the following:
1. Obtains the names of all installed packages (if I used python-apt I could probably do this better)
2. Looks through the list of files that each package "owns" on your system, and stores their atime and mtime (access time and modification time) with that package
3. Then it looks through each package and finds which have nothing but atimes and mtimes older than X number of years/months/days/etc.
Here is a link to my current working version (if I update it, it will be updated here): http://strike.homelinux.org/~ddipaolo/python/apt-oldpkgs/apt_oldpkgs.py
And here is a snapshot of what I have:
#!/usr/bin/env python
import os
import os.path
import stat
import time
_minute = 60
_hour = 60 * _minute
_day = 24 * _hour
_month = 30 * _day
_year = 365 * _day
LISTFILES_DIR = "/var/lib/dpkg/info"
LISTFILES_SUFFIX = ".list"
OLDDATE = time.time() - _year # Anything older than 1 year is considered "old"
class deb_file(file):
def __init__(self, name, mode):
file.__init__(self, name, mode)
self.atime = os.stat(self.name)[stat.ST_ATIME]
self.mtime = os.stat(self.name)[stat.ST_MTIME]
def is_older_than(self, date):
# date is in good ol' UNIX time - number of seconds since the epoch,
# and we compare to the atime and mtime of the file, if both of them
# are older, then we return true. Otherwise it's false.
return date > self.atime and date > self.mtime
class deb_package:
def __init__(self, name):
self.name = name
self.listfile_name = "%s/%s%s" % (LISTFILES_DIR, name, LISTFILES_SUFFIX)
self.filenames = self.get_files()
def get_files(self):
# We want to look at only leaves of the directory tree that are in the
# .list file (that is, only files and not directories)
actual_files = []
listfile = file(self.listfile_name, "r")
for filename in listfile.readlines():
filename = filename.strip()
if not os.path.isdir(filename):
actual_files.append(filename)
listfile.close()
return actual_files
def is_older_than(self, date):
# Returns true if all the atimes and mtimes of the files in this
# package are older than date (seconds since the epoch)
for pkg_filename in self.filenames:
try:
pkg_file = deb_file(pkg_filename, "r")
except IOError:
return 0 # Permission denied
if not pkg_file.is_older_than(date): return 0
pkg_file.close()
return 1
def get_package_names():
# For some weird reason (maybe I'm misunderstanding scope within for
# loops), I couldn't just use orig_list.remove on anything NOT ending with
# LISTFILES_SUFFIX, as it wouldn't remove everything appropriate and I
# think it actually removed some stuff I didn't want it to.
pkg_list = []
orig_list = os.listdir(LISTFILES_DIR)
for filename in orig_list:
if filename.endswith(LISTFILES_SUFFIX):
filename = filename[:len(filename)-len(LISTFILES_SUFFIX)]
if filename not in pkg_list:
pkg_list.append(filename)
return pkg_list
if __name__ == "__main__":
old_pkgs = []
pkg_list = get_package_names()
for pkg_name in pkg_list:
new_pkg = deb_package(pkg_name)
print "checking " + new_pkg.name
if new_pkg.is_older_than(OLDDATE):
old_pkgs.append(new_pkg)
print "The following packages were found to be old:"
for pkg in old_pkgs:
print "\t" + pkg.name
1. Obtains the names of all installed packages (if I used python-apt I could probably do this better)
2. Looks through the list of files that each package "owns" on your system, and stores their atime and mtime (access time and modification time) with that package
3. Then it looks through each package and finds which have nothing but atimes and mtimes older than X number of years/months/days/etc.
Here is a link to my current working version (if I update it, it will be updated here): http://strike.homelinux.org/~ddipaolo/python/apt-oldpkgs/apt_oldpkgs.py
And here is a snapshot of what I have:
#!/usr/bin/env python
import os
import os.path
import stat
import time
_minute = 60
_hour = 60 * _minute
_day = 24 * _hour
_month = 30 * _day
_year = 365 * _day
LISTFILES_DIR = "/var/lib/dpkg/info"
LISTFILES_SUFFIX = ".list"
OLDDATE = time.time() - _year # Anything older than 1 year is considered "old"
class deb_file(file):
def __init__(self, name, mode):
file.__init__(self, name, mode)
self.atime = os.stat(self.name)[stat.ST_ATIME]
self.mtime = os.stat(self.name)[stat.ST_MTIME]
def is_older_than(self, date):
# date is in good ol' UNIX time - number of seconds since the epoch,
# and we compare to the atime and mtime of the file, if both of them
# are older, then we return true. Otherwise it's false.
return date > self.atime and date > self.mtime
class deb_package:
def __init__(self, name):
self.name = name
self.listfile_name = "%s/%s%s" % (LISTFILES_DIR, name, LISTFILES_SUFFIX)
self.filenames = self.get_files()
def get_files(self):
# We want to look at only leaves of the directory tree that are in the
# .list file (that is, only files and not directories)
actual_files = []
listfile = file(self.listfile_name, "r")
for filename in listfile.readlines():
filename = filename.strip()
if not os.path.isdir(filename):
actual_files.append(filename)
listfile.close()
return actual_files
def is_older_than(self, date):
# Returns true if all the atimes and mtimes of the files in this
# package are older than date (seconds since the epoch)
for pkg_filename in self.filenames:
try:
pkg_file = deb_file(pkg_filename, "r")
except IOError:
return 0 # Permission denied
if not pkg_file.is_older_than(date): return 0
pkg_file.close()
return 1
def get_package_names():
# For some weird reason (maybe I'm misunderstanding scope within for
# loops), I couldn't just use orig_list.remove on anything NOT ending with
# LISTFILES_SUFFIX, as it wouldn't remove everything appropriate and I
# think it actually removed some stuff I didn't want it to.
pkg_list = []
orig_list = os.listdir(LISTFILES_DIR)
for filename in orig_list:
if filename.endswith(LISTFILES_SUFFIX):
filename = filename[:len(filename)-len(LISTFILES_SUFFIX)]
if filename not in pkg_list:
pkg_list.append(filename)
return pkg_list
if __name__ == "__main__":
old_pkgs = []
pkg_list = get_package_names()
for pkg_name in pkg_list:
new_pkg = deb_package(pkg_name)
print "checking " + new_pkg.name
if new_pkg.is_older_than(OLDDATE):
old_pkgs.append(new_pkg)
print "The following packages were found to be old:"
for pkg in old_pkgs:
print "\t" + pkg.name