#! /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()