#! /usr/local/bin/python
# findports.py
# Searchs the ports database.
# Ernesto Mendez / Kenneth Klein der.kunstler@gmail.com / rewt.axs@gmail.com
import os, sys
from copy import copy
progname = os.path.basename( sys.argv[0] )
help = """** Der_Kunstler 2006 ( der.kunstler@gmail.com ) **
%s:
A small utility to search for ports in FreeBSD, in which
you can specify the output that you want.
usage: %s [ options ] portname
Options:
-k -- Search keywords, instead of names
-p -- Include the port's path
-i -- Include information about the port
-m -- Include the port's maintainer
-b -- Inclcude the B-deps
-r -- Include the R-deps
-w -- Include the port's webpage
-h -- print this help message
""" % ( progname.replace(".py","").upper(), progname.replace("./", ""))
def parseopts():
""" Parse the options and do some checks."""
# check if no arguments:
if len( sys.argv ) == 1:
print help
sys.exit(1)
# check if the user wants to print the help.
if len(sys.argv) == 2 and (sys.argv[-1] == "-h" or sys.argv[-1] == "h" or sys.argv[-1] == "--help" \
or sys.argv[-1] == "-help" or sys.argv[-1] == "help"):
print help
sys.exit(1)
# check if the user entered option but did not enter the portname
if "-" in sys.argv[-1]:
print "\n>> Enter the portname in order to proceed.\n"
sys.exit(1)
portname = ""
if len(sys.argv) == 2 and len(sys.argv[-1]) > 0 and "-" not in sys.argv[-1]:
portname=sys.argv[-1]
# return the portname, and no options
return portname, []
# Options:
# -k search with keyword, instead of name
# -p port path ( does not need to be specified )
# -i port info
# -m port maintainer
# -b B-deps
# -r R-deps
# -w webpage information
# -h, --help, h, -help print help
options ="pimbrwhk"
parsed_opts = []
opts = sys.argv[1:-1]
# clean the opts ( no - switch )
for i in range( len(opts) ):
opts[i] = opts[i].replace("-","").lower()
# check if the options have only 1 character
for opt in opts:
if len(opt) == 1:
pass # option is OK.
else:
print "\n>> Invalid Option: [ %s ], use -h for available options.\n" % opt
sys.exit(1)
# check if the options are available
for opt in opts:
if opt in options:
pass
else:
print "\n>> Unknown Option: [ %s ], use -h for available options.\n" % opt
sys.exit(1)
return sys.argv[-1], opts
def getbuffer(portname, opts):
""" Enters the ports directory, searches for the portname, and gets
all th information pertaining to the port,
Return Value: [ A string buffer, containing the %make search output ] """
os.chdir("/usr/ports")
if "k" in opts:
value="key"
else:
value="name"
os.system("make search %s=%s > /tmp/portsearch" % ( value, portname ) )
buf = open("/tmp/portsearch", "r").readlines()
os.system("rm -f /tmp/portsearch")
# Return an array, containing the strings of the readlines() output.
return buf
class PortClass:
""" The ports class, containing all the information to be printed in separate
variables, to enabling data filtering to the output. """
def __init__(self, port, path, info, maint, b_deps, r_deps, www):
self.port = port.strip()
self.path = path.strip()
self.info = info.strip()
self.maint = maint.strip()
self.b_deps = b_deps.strip()
self.r_deps = r_deps.strip()
self.www = www.strip()
# For debugging purposes.
def printf(self):
print self.port, self.path, self.info, self.maint, self.b_deps, self.r_deps, self.www
# print, depending on the options
def format(self, args):
opts = []
for i in args:
if i.lower() != "k":
opts.append(i)
print self.port
if "p" in opts:
print self.path
if "i" in opts:
print self.info
if "m" in opts:
print self.maint
if "b" in opts:
print self.b_deps
if "r" in opts:
print self.r_deps
if "w" in opts:
print self.www
if len(opts) > 0:
print "\n" ,
def create_ports(buf):
""" Creates and classifies the ports classes, returning an array that contains
port classes with all the matches of the ports search. """
# reverse the buffer array, to then use the pop() function.
ports_list = []
buf.reverse()
try:
while len(buf) > 0:
port = buf[-1]
path = buf[-2]
info = buf[-3]
maint = buf[-4]
b_deps = buf[-5]
r_deps = buf[-6]
www = buf[-7]
# create the ports class
newclass = PortClass( port, path, info, maint, b_deps, r_deps, www )
# update the ports list
ports_list.append( newclass )
# rip the last port information from the buffer
buf = buf[:-8]
continue
# When you hit the wall, exit!!! :-)
except IndexError:
pass
# Return the list containing all the PortClass instances.
return ports_list
def main():
""" Main function. """
portname, opts = parseopts()
buf = getbuffer(portname, opts)
ports_list = create_ports(buf)
print "\n",
for port in ports_list:
if port.port == ports_list[-1].port: # is the port the last one, if so, append a newline.
port.format(opts)
print "\n",
else:
port.format(opts)
if __name__ == "__main__":
main()