3
# Copyright (C) 2007 Enrico Zini <enrico@debian.org>
5
# This program is free software; you can redistribute it and/or modify it under
6
# the terms of the GNU General Public License as published by the Free Software
7
# Foundation; either version 2 of the License, or (at your option) any later
10
# Navigate among related Debian packages
14
# Requires python-extractor, python-magic and python-debtags
15
from debian_bundle import debtags
17
from optparse import OptionParser
23
class Parser(OptionParser):
24
def __init__(self, *args, **kwargs):
25
OptionParser.__init__(self, *args, **kwargs)
28
sys.stderr.write("%s: error: %s\n\n" % (self.get_prog_name(), msg))
29
self.print_help(sys.stderr)
32
if __name__ == '__main__':
33
parser = Parser(usage="usage: %prog [options] pkgname",
34
version="%prog "+ VERSION,
35
description="walk through Debian packages")
36
parser.add_option("--tagdb", default="/var/lib/debtags/package-tags", help="Tag database to use (default: %default)")
38
(options, args) = parser.parse_args()
41
parser.error("Please provide the name of an initial package")
45
tagFilter = re.compile(r"^special::.+$|^.+::TODO$")
46
db.read(open(options.tagdb, "r"), lambda x: not tagFilter.match(x))
48
aptCache = apt.Cache()
50
# Maximum number of previous packages to remember
52
# Initial package selection
55
# Loop until the user chooses to quit
58
# Compute a package weight according to how old it is in the
61
for idx, pkg in enumerate(trail):
62
pkgweight[pkg] = 1.-(idx/maxlen)
64
# For every tag, find the number of packages in trail that have the tag
67
for tag in db.tagsOfPackage(pkg):
69
tagscores[tag] += pkgweight[pkg]
71
tagscores[tag] = pkgweight[pkg]
73
# Divide every tag score by the number of packages in the trail,
74
# obtaining a 'tag weight'. A package can be later scored by summing
75
# the weight of all its tags.
76
for tag in tagscores.iterkeys():
77
tagscores[tag] = float(tagscores[tag]) / float(len(trail))
79
# Find the merged tagset of the packages in trail
80
trailtags = set(tagscores.keys())
82
# Get the list of packages whose tagsets intersect the trail tagset
84
for pkg, tags in db.iterPackagesTags():
88
# Score every package by the sum of the weight of its tags
91
for tag in db.tagsOfPackage(pkg):
93
score += tagscores[tag]
96
# Show the first 20 packages in reverse score order
97
#display = sorted(nextpkgs - set(trail), key=pkgscore, reverse=True)[:20]
98
display = sorted(nextpkgs, key=pkgscore, reverse=True)[:20]
99
for num, pkg in enumerate(display):
100
aptpkg = aptCache[pkg]
101
desc = aptpkg.rawDescription.split("\n")[0]
102
print "%2d) %s - %s" % (num + 1, pkg, desc)
104
# Ask the user to choose a new package
106
ans = raw_input("> ").strip()
112
if num < len(display):
113
# TODO: on a different kind of interface, display the full
115
trail = [display[num]] + trail[:maxlen]
118
print "The number is too high"