/usr/share/command-not-found/CommandNotFound/CommandNotFound.py is in command-not-found 0.2.38-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 | # (c) Zygmunt Krynicki 2005, 2006, 2007, 2008
# Licensed under GPL, see COPYING for the whole text
import sys, os, os.path, gdbm, posix, grp, string
from util import gettext_wrapper as _
class BinaryDatabase:
def __init__(self, filename):
self.db = None
if filename.endswith(".db"):
try:
self.db = gdbm.open(filename, "r")
except gdbm.error, err:
print >>sys.stderr, "Unable to open binary database %s: %s" % (filename, err)
def lookup(self, key):
if self.db and self.db.has_key(key):
return self.db[key]
else:
return None
class FlatDatabase:
def __init__(self, filename):
self.rows = []
dbfile = file(filename)
for line in (line.strip() for line in dbfile):
self.rows.append(line.split("|"))
dbfile.close()
def lookup(self, column, text):
result = []
for row in self.rows:
if row[column] == text:
result.append(row)
return result
def createColumnByCallback(self, cb, column):
for row in self.rows:
row.append(cb(row[column]))
def lookupWithCallback(self, column, cb, text):
result = []
for row in self.rows:
if cb(row[column],text):
result.append(row)
return result
class ProgramDatabase:
(PACKAGE, BASENAME_PATH) = range(2)
def __init__(self, filename):
basename = os.path.basename(filename)
self.db = BinaryDatabase(filename)
self.component = self.db.db[':component:']
def lookup(self, command):
result = self.db.lookup(command)
if result:
return result.split("|")
else:
return []
def similar_words(word):
""" return a set with spelling1 distance alternative spellings
based on http://norvig.com/spell-correct.html"""
alphabet = 'abcdefghijklmnopqrstuvwxyz-_'
s = [(word[:i], word[i:]) for i in range(len(word) + 1)]
deletes = [a + b[1:] for a, b in s if b]
transposes = [a + b[1] + b[0] + b[2:] for a, b in s if len(b)>1]
replaces = [a + c + b[1:] for a, b in s for c in alphabet if b]
inserts = [a + c + b for a, b in s for c in alphabet]
return set(deletes + transposes + replaces + inserts)
class CommandNotFound:
programs_dir = ""
prefixes = ("/bin",
"/usr/bin",
"/usr/local/bin",
"/sbin", "/usr/sbin",
"/usr/local/sbin",
"/usr/games")
def __init__(self, data_dir=os.sep.join(
('/','var','cache','command-not-found'))):
self.programs = []
self.priority_overrides = []
p = os.path.join(data_dir, "priority.txt")
if os.path.exists(p):
self.priority_overrides = map(string.strip, open(p).readlines())
self.components = ['main','universe','contrib','restricted','non-free',
'multiverse']
self.components.reverse()
for filename in os.listdir(os.path.sep.join([data_dir, self.programs_dir])):
self.programs.append(ProgramDatabase(os.path.sep.join([data_dir, self.programs_dir, filename])))
if not self.programs:
print _("Could not find the database of available applications, "
"run update-command-not-found as root to fix this")
try:
self.user_can_sudo = grp.getgrnam("admin")[2] in posix.getgroups()
except KeyError:
self.user_can_sudo = False
def print_spelling_suggestion(self, word, min_len=3, max_len=15):
" try to correct the spelling "
if len(word) < min_len:
return
possible_alternatives = []
for w in similar_words(word):
packages = self.getPackages(w)
for (package, comp) in packages:
possible_alternatives.append((w, package, comp))
if len(possible_alternatives) > max_len:
print >>sys.stderr, _("No command '%s' found, but there are %s similar ones") % (word, len(possible_alternatives))
elif len(possible_alternatives) > 0:
print >>sys.stderr, _("No command '%s' found, did you mean:") % word
for (w, p, c) in possible_alternatives:
print >>sys.stderr, _(" Command '%s' from package '%s' (%s)") % (w, p, c)
def getPackages(self, command):
result = set()
for db in self.programs:
result.update([(pkg,db.component) for pkg in db.lookup(command)])
return list(result)
def getBlacklist(self):
try:
blacklist = file(os.sep.join((os.getenv("HOME", "/root"), ".command-not-found.blacklist")))
return [line.strip() for line in blacklist if line.strip() != ""]
except IOError:
return []
else:
blacklist.close()
def _getSourcesList(self):
try:
import apt_pkg
from aptsources.sourceslist import SourcesList
apt_pkg.init()
except (SystemError, ImportError), e:
return []
sources_list = set([])
for source in SourcesList():
if not source.disabled and not source.invalid:
for component in source.comps:
sources_list.add(component)
return sources_list
def sortByComponent(self, x, y):
# check overrides
if (x[0] in self.priority_overrides and
y[0] in self.priority_overrides):
# both have priority, do normal sorting
pass
elif x[0] in self.priority_overrides:
return -1
elif y[0] in self.priority_overrides:
return 1
# component sorting
try:
xidx = self.components.index(x[1])
except:
xidx = -1
try:
yidx = self.components.index(y[1])
except:
xidx = -1
return (yidx-xidx) or cmp(x,y)
def advise(self, command, ignore_installed=False):
" give advice where to find the given command to stderr "
def _in_prefix(prefix, command):
" helper that returns if a command is found in the given prefix "
return (os.path.exists(os.path.join(prefix, command)) and
not os.path.isdir(os.path.join(prefix, command)))
if command.startswith("/"):
if os.path.exists(command):
prefixes = [os.path.dirname(command)]
else:
prefixes = []
else:
prefixes = [prefix for prefix in self.prefixes if _in_prefix(prefix, command)]
# check if we have it in a common prefix that may not be in the PATH
if prefixes and not ignore_installed:
if len(prefixes) == 1:
print >>sys.stderr, _("Command '%(command)s' is available in '%(place)s'") % {"command": command, "place": os.path.join(prefixes[0], command)}
else:
print >>sys.stderr, _("Command '%(command)s' is available in the following places") % {"command": command}
for prefix in prefixes:
print >>sys.stderr, " * %s" % os.path.join(prefix, command)
missing = list(set(prefixes) - set(os.getenv("PATH", "").split(":")))
if len(missing) > 0:
print >>sys.stderr, _("The command could not be located because '%s' is not included in the PATH environment variable.") % ":".join(missing)
if "sbin" in ":".join(missing):
print >>sys.stderr, _("This is most likely caused by the lack of administrative priviledges associated with your user account.")
return False
# do not give advice if we are in a situation where apt-get
# or aptitude are not available (LP: #394843)
if not (os.path.exists("/usr/bin/apt-get") or
os.path.exists("/usr/bin/aptitude")):
return False
if command in self.getBlacklist():
return False
packages = self.getPackages(command)
if len(packages) == 0:
self.print_spelling_suggestion(command)
elif len(packages) == 1:
print >>sys.stderr, _("The program '%s' is currently not installed. ") % command,
if posix.geteuid() == 0:
print >>sys.stderr, _("You can install it by typing:")
print >>sys.stderr, "apt-get install %s" % packages[0][0]
elif self.user_can_sudo:
print >>sys.stderr, _("You can install it by typing:")
print >>sys.stderr, "sudo apt-get install %s" % packages[0][0]
else:
print >>sys.stderr, _("To run '%(command)s' please ask your administrator to install the package '%(package)s'") % {'command': command, 'package': packages[0][0]}
elif len(packages) > 1:
packages.sort(self.sortByComponent)
print >>sys.stderr, _("The program '%s' can be found in the following packages:") % command
for package in packages:
print >>sys.stderr, " * %s" % package[0]
if posix.geteuid() == 0:
print >>sys.stderr, _("Try: %s <selected package>") % "apt-get install"
elif self.user_can_sudo:
print >>sys.stderr, _("Try: %s <selected package>") % "sudo apt-get install"
else:
print >>sys.stderr, _("Ask your administrator to install one of them")
return len(packages) > 0
|