#! python: #w#VIC IQ command- search engine with keyed word, sub-words and multi-file depth. # # Copyright 1998, 2001, 2003 by Timothy Rue <3seas@threeseas.net> # # VIC IQ command: version 0.5.1.python # IQ command SYNTAX: python IQ.py FROM WORD SUBS... # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation version 2 # of the License. http://www.gnu.org/copyleft/gpl.html # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # Or access http://www.gnu.org/copyleft/gpl.html # ############################################################################# #August 14-25, 2003 --- IQ version 0.5.1.python - fixed 4 output bugs # bug - Double output of non-filekey first line - fixed # bug - print statement bug that added leading space - fixed # bug - subkey not in active word was not caught in select - fixed # output of filename was fixed to not have leading file key tag # also did some markup for IQ parsing of source # #July 23, 2003 --- IQ version 0.5.python - added the -e Execute option. # went from 0.351 to 0.5 to put into sync with ID command. # #June 27, 2001 --- IQ version 0.351.python - put in if file exists ("lnswitch") # switch for linenumbers. This is for the py2exe version. # #June 18, 2001 --- IQ version 0.35.python # Thanks to Alex Martelli in the usenet newsgroups for his simple comment # regarding how easy it is to add Internet file access to IQ and the guys # on IRC for helping me work thru some bugs in my attempt to get it going, # WE NOW HAVE Internet file access in IQ!!!! Just use a valid URL anywhere # you'd use a filename. Considering I work in a field not dealing with # computers and we are doing 56 hr 6 day weeks going into even more hour # 7 days a week, such help is greatly appriciated. I'd not gotten it done # so soon otherwise!!!! - Now I just need to start keeping list of names # for those who have helped!!! # #JUNE 14, 2001 --- IQ Version 0.34.python # Bug Fix - In the porting process some things were rewritten and this # caused a variable to not get inherently set. Now that variable gets # intentionally set. The result of this bug was an infinite loop of # outputting the same line. # #New in IQ Version 0.34.python: # I've added outputing the word/sub/file keys along with the text you # would normally get. This should help people to understanding what is # going on. The '-s' (silence warnings) options removes this from the # the output, along with still removing warnings. This way the 'meat' # is still able to be output by itself. # # Added better 'filekey' handeling. This is the first line of an .iq # file and can be considered the "legend" that tells IQ how to see the # files words/subs/file keys. But along with using default and previous # "filekeys", now IQ can handle improper filekeys, using as much as it # can of a bad filekey. # # Corrected or improved some output formatting and warning messages. # # Oh yeah, As in the first version in the python language, arexx port # addressing has been removed since other systems that can run this # python program don't have Arexx or application arexx ports. However, # the "pipebridge" used to interface Rebol with the AmigaOS side can be # adapted so to return this Arexx port addressing. # #YET TO DO: is a long list (the whole VIC) that includes GUI interfaces. # It shouldn't be two hard to adapt the GUI4CLI interface (for Amiga). # But for other systems, TK might be better. However, the author of # GUI4CLI has been working on a PC version.....:) # # As always, I'm open to anyone actually willing to help move this GPL # project forward. # ############################################################################# #w#System Modules import re, sys, string, os #w#test for linenumbers file "lnswitch.on" existing and set linenumbers try: test = open("lnswitch.on",'r') test.close() linenumbers = 1 except: #set linenumbers to 1 to show line numbers & IQ stacks. set to 0 otherwise# linenumbers = 0 #w#to compile into a stand alone use "freeze" or "py2exe" or # gmcm's installer - ask google about gmcm's installer. #w#set starting values for some variables and lists ex=tellnot=tellkeys=no_tcp=endloop=iqsu=iqsc=i=t=0 IQ_stack=[] IQ_stacku=[] key_count=[0] key_level=-1 tn = 1 #w#parse command line arguements if len(sys.argv) > 1: fromf = sys.argv[1] else: fromf = '' if len(sys.argv) > 2: word = sys.argv[2] else: word = '' if len(sys.argv) > 3: subs = sys.argv[3] else: subs = '' if len(sys.argv) > 4: subl = sys.argv[4:] else: subl = '' #w#help options if fromf in ('','?','help','-h','-?'): print "VIC IQ v0.5.1 - search engine with keyed word, sub-words and multi-file depth." print "Copyright 1998, 2001 by Timothy Rue <3seas@threeseas.net>" print "GNU General Public License version 2 - http://www.gnu.org/copyleft/gpl.html" print "" print "To turn on filename@line#'s make empty file named 'lnswitch.on' in same dir." print "" print "Help legend: (pattern = regular expression)" print "optional=< >, one arguement=[ ], any number of arguements={ }" print "" print "FOR HELP:" print "python IQ.py -OR- python IQ.py [ ? | -? | -h | help ]" print "" print "COMMAND LINE:" print "python IQ.py < -e | -s, -k > [from_iq_file] [word|pattern] {sub|pattern}" print "" print "EXECUTE OUTPUT: (automatic '-s' option and ignores '-k' option)" print "python ID.py [-e | -E ] [from_id_file] [word|pattern] {sub|pattern}" print "" print "TO SILENCE WARNINGS: (use -s before -k)" print "python IQ.py [ -s | -S ] [from_iq_file] [word|pattern] {sub|pattern}" print "" print "FOR UNIQUE KEYS LIST (filekeys and w/word and sub pattern matching):" print "python IQ.py [ -k | -K | -Keys | -KEYS ] [from_iq_file] [word|pattern] {sub|pattern}" print "---" sys.exit(0) #w#check for -e option - Execute if string.upper(fromf) == '-E': ex = 1 tellnot = 1 fromf = word word = subs subs = subl #w#check for -s option - Silence Warnings if string.upper(fromf) == '-S': tellnot = 1 fromf = word word = subs subs = subl #w#try to get a tcp socket and set no_tcp variable to 1 if not available. try: import urllib except: no_tcp = 1 if tellnot == 0: print "WARNING: NO TCP/IP stack running, local file access only" #w#check for -k option and print top line if selected key = string.upper(fromf) if (key == '-K' or key == '-KEYS'): if (ex != 1) : tellkeys= 1 fromf = word if (tellnot == 1): word = subs[0] subs = subs[1:] else: word = subs subs = subl print 'Listing Unique KEYS (first time found - filekeys and w/word and sub pattern matching):' #w#get all subs patterns into subs if (tellnot == 0 and tellkeys== 0 and subl): subl.append(subs) subs = subl del subl #w#calculate # of sub words given if type(subs) == type('string'): if len(subs) > 0: subn=1 else: subn=0 else: subn = len(subs) #w#test for valid file arguement try: if no_tcp == 0: iqfile = urllib.urlopen(fromf) else: iqfile = open(fromf,'r') except: print "Error: IQ file '%s' not found" % fromf sys.exit(10) #w#Set key list then read first line of IQ file and checks for the first word to = key[0] variable. key = ['filekey', 'word:', 'sub:', 'file:', 1] #w#read first line of file inline = iqfile.readline() ln = 1 #w#test for proper filekey if re.match(key[0], inline): templine = string.strip(inline) test = len(string.split(inline)) if test == 4: key[0:4] = string.split(inline) if tellnot == 0 and tellkeys == 0: print '%s' % string.join(key[0:4]) key_count[0] = string.strip(inline) if test < 4: key[0:test] = string.split(inline) inline = string.join(key[0:4]) + "\n" key_count[0] = string.strip(inline) if test > 4: tempstring = string.split(inline) key[0:4] = tempstring[0:4] inline = string.join(key[0:4]) + "\n" key_count[0] = string.strip(inline) if tellnot == 0 and test != 4: print 'WARNING: file> %s %s' % (fromf,templine,) print 'USING given "filekeys" (max 3) overlayed on default keys to get> %s' % string.join(key[0:4]) print '======================' if tellkeys == 0: print '%s' % inline, if linenumbers != 0: print '^IQ Stack-> %s@Line#%s' %(fromf, ln,) del test del templine else: i = -1 if tellnot == 0: print 'NOTICE: file> %s %s -1) and (key[4] == 1) : fromt = string.strip(inline[len(key[3]):]) # /* check if file is self recursive */ if fromf == fromt : pass # /* break from select */ else: # /* set/reset IQ_stacks position and break variable */ position = -1 # /* check if in used stack */ if iqsu > 0 : for i in range(0,iqsu): #print 'Checking Used filename stack %s' % IQ_stacku[i] if IQ_stacku[i] == fromt: position = i break if position > -1 : pass # /* break from select */ else: # /* check if file exist/is valid */ try: if no_tcp == 0: testfile = urllib.urlopen(fromt) testfile.close() else: testfile = open(fromt,'r') testfile.close() except: if tellnot == 0 : print "WARNING: IQ file> %s %s@Line#%s" % (string.strip(fromt), fromf, ln) position = -2 if position == -2 : pass # /* break from select */ else: # /* check if in current stack - if so save current settings, # read in previous settings, sort stack, goto last line of file read */ if iqsc > 0 : for i in range(0,iqsc): #print 'fromt %s == IQ_stack[i][0] %s'%(fromt, IQ_stack[i][0]) if IQ_stack[i][0] == fromt : position = i break if position > -1 : IQ_stackt = [fromf, key[1], key[2], key[3], key[4], key_level, ln ] fromf, key[1], key[2], key[3], key[4], key_level, ln, = IQ_stack[position] del IQ_stack[position] IQ_stack.append(IQ_stackt) iqfile.close() if no_tcp == 0: iqfile = urllib.urlopen(fromf) else: iqfile = open(fromf, 'r') for n in range(0, ln+1): iqfile.readline() position = -2 #print 'Second + time file encountered %s' %IQ_stack if position == -2 : pass # /* break from select */ else: # /* if not in either stack - save current settings and # read in key of new file if key exist */ if position == -1 : iqsc = iqsc + 1 IQ_stack.append([fromf, key[1], key[2], key[3], key[4], key_level, ln]) fromf = fromt iqfile.close() #print 'First time file encountered %s' % IQ_stack # /* Check and build array of words, subs and files*/ if tellkeys== 1 and key[4] == 1 : inline = string.strip(inline) newkey=1 for t in range(0, tn): #print '*****key_count[%s] cmp to inline<%s>' %(key_count[t],inline) if key_count[t] == inline : newkey=0 break if newkey: key_count.append(inline) #print 'key_count********* -> %s' % key_count tn = tn + 1 # /* print files key if not using -s flag and within selected # word/sub/file scope*/ if tellnot == 0 and key[4] == 1 : if tellkeys == 1: print 'looking in file-> %s' % fromf else: # sys.stdout.write() used because print here seems to add a leading space #print '%s' % inline, sys.stdout.write('%s' % inline) if no_tcp == 0: iqfile = urllib.urlopen(fromf) else: iqfile = open(fromf,'r') inline = iqfile.readline() ln = 1 key_level = 0 # /* test for proper filekey */ if re.match(key[0], inline): templine = string.strip(inline) test = len(string.split(inline)) if test == 4: key[0:4] = string.split(inline) if test < 4: key[0:test] = string.split(inline) inline = string.join(key[0:4]) + "\n" if test > 4: tempstring = string.split(inline) key[0:4] = tempstring[0:4] inline = string.join(key[0:4]) + "\n" if tellnot == 0 and test != 4: print 'WARNING: file> %s %s' % (fromf,templine,) print 'USING given "filekeys" (max 3) overlayed on previous keys to get> %s' % string.join(key[0:4]) print '======================' #print '%s' % inline, del test del templine else: i = -1 if tellnot == 0: print 'NOTICE: file> %s %s -1) and key_level > 0 : key[4] = 0 key_level = 1 # /* test arg sub match (within matching word)*/ if subn > 1: for t in range(0, (subn)): subpattern = key[2] + subs[t] #print 'subpattern %s inline %s' % (subpattern, inline) if re.match(subpattern, inline) : key_level = 2 key[4] = 1 break elif subn == 1: subpattern = key[2] + string.join(subs[0:],'') #print 'subpattern %s cmp inline %s' % (subpattern, inline) if re.match(subpattern, inline) : key_level = 2 key[4] = 1 # /* if w/blank sub */ if (string.strip(inline) == key[2]) and (key_level == 1) : key[4] = 1 #s#WHEN WORD LEVEL -------------------------------------------------- elif (keyr1 > -1) : key[4] = 0 key_level = 0 wordy = '' # /* if arg word match */ if word != '': wordy = key[1] + word if re.match(wordy, inline) : key_level = 1 key[4] = 1 # /* if exiting word key w/blank word */ if string.strip(inline) == key[1] : key[4] = 1 #s#WHEN none of the above and '-s' used ----------------------------- elif tellkeys== 1 : pass #s#WHEN not using '-s' and a sub key not in active word level ------- elif key_level == 0 and keyr2 == 0 : pass #s## ??? can this ever happen ??? # else : print 'ERROR: in file %s at linenumber> %s ... OR in Command line %s' % (fromf, ln, sys.argv) # END OF SELECT======================================================== #w#keyline plus output # -IQ version 0.34.python- allows keys to be output too - w/o -s flag # -output key line when no -s flag used and within selected word/sub/file scope if linetest != 0 and tellnot == 0 and tellkeys != 1 and key[4] == 1 and i == 0 : print '%s' %inline, #w#** Handle EOF and IQ stacks ************************************* if inline == '': if iqsc > 0 : iqfile.close() iqsc = iqsc -1 iqsu = iqsu +1 IQ_stacku.append(fromf) fromf, key[1], key[2], key[3], key[4], key_level, ln = IQ_stack[iqsc] del IQ_stack[iqsc] if no_tcp == 0: iqfile = urllib.urlopen(fromf) else: iqfile = open(fromf,'r') for n in range(0, ln+1): iqfile.readline() else : iqsu = iqsu +1 IQ_stacku.append(fromf) endloop=1 #w#**COLLECT KEYS- Make list of unique Keys if -k option selected ******** if linetest != 0 and tellkeys== 1 and key[4] == 1 and flipflop == 0 : # /*Check and build array of words, subs and files*/ inline = string.strip(inline) newkey = 1 for t in range(0, tn): #print '#####key_count[%s] cmp to inline<%s>' %(key_count[t],inline) if key_count[t] == inline: newkey=0 break if newkey: key_count.append(inline) #print 'key_count######## -> %s' % key_count tn = tn+1 #w#TELL STACKS OUTPUT multi-file test/IQ_stacks. Set 'linenumbers' != 0, to use* # build and print completed files list # if linenumbers != 0 and inline == '': result = IQ_stacku[0] for t in range(1, (iqsu)): result = result + ',' + IQ_stacku[t] print 'IQ Search Completed File(s)->%s' % result if endloop: # endloop set in handeling EOF and IQ stacks above # break ############ BREAK From Do Forever loop############# if linenumbers != 0 and inline != '': if iqsc > 0 : result = ' '+(IQ_stack[0][0])+'@Line#'+str(IQ_stack[0][6]) for t in range(1, (iqsc)): result = result+' '+(IQ_stack[t][0])+'@Line#'+str(IQ_stack[t][6]) # This is the PK files IQ stack when more than one item # print '^IQ Stack->%s %s@Line#%s' %(result, fromf, ln,) else : # This is the PK files IQ stack when only one item # print '^IQ Stack-> %s@Line#%s' %(fromf, ln,) #w######################## Do Forever loop END ##################### #w#TELL/LIST KEYS- unique keys if option -k selected # if tellkeys== 1 : for t in range(0, tn): print '%s' % key_count[t] kec = len(key_count) print 'Unique KEY count = %s' % kec, sys.exit(0) # #