ped_dialog.file_find module
module to implement search for files and search for pattern in files used in the ped editor
# Copyright 2009 James P Goodwin ped tiny python editor """ module to implement search for files and search for pattern in files used in the ped editor """ import curses import curses.ascii import sys import os import tempfile from ped_dialog import dialog from ped_core import editor_common import re import traceback from array import array from ped_dialog.message_dialog import message from ped_dialog.stream_select import StreamSelectComponent from ped_dialog.file_browse import FileBrowseComponent from ped_core import keytab def sanitize( text ): """ if a string has binary chunks replace them with hex return fixed up string """ inbytes = array('B') inbytes.fromstring(text) hexchars = "0123456789ABCDEF" outtext = "" index = 0 for i in inbytes: if (i < 32 and (i not in [9,10,13])) or i > 127: hexout = hexchars[i//16] + hexchars[i%16] outtext = outtext + hexout else: outtext = outtext + text[index] index = index + 1 return outtext def contains(fullpath, pattern, found): """ test to see if the file referenced by fullpath contains pattern write result lines to file object found """ try: line = 0 fl = open(fullpath, "r") inline = fl.readline(2048) while inline: sl = sanitize(inline) if re.search(pattern,sl): print("%s:%d:%s"%(fullpath,line,sl.rstrip()), file=found) inline = fl.readline(2048) line += 1 except Exception as e: print("%s:%d:ERROR %s"%(fullpath,line,str(e)), file=found) def where( path, fpat, cpat, recurse, scr ): """ recursively search for a pattern in files starting with path, files matchin re fpat, containing re cpat, if recurse == False only do one directory, if scr is non null then report status in a message dialog""" found = tempfile.TemporaryFile(mode="w+") for (dirpath, dirnames, filenames) in os.walk(path): for f in filenames: if f[0] == ".": continue if f[-1] == "~": continue if f.endswith(".bak") or f.endswith(".pyc"): continue fullpath = os.path.join(dirpath,f) if re.search(r"\.svn",fullpath): continue try: if re.search(fpat,fullpath): if scr and cpat: message(scr,"Searching",fullpath,False) if cpat: contains(fullpath, cpat, found) else: print("%s"%(fullpath), file=found) except Exception as e: print("%s:0:ERROR:%s"%(fullpath,str(e)), file=found) if not recurse: break found.seek(0,0) return found class FileFindDialog(dialog.Dialog): """ dialog subclass that implements a file find dialog with a list of found files/lines preview window and fields for file pattern, contents pattern, recursive search, starting path, buttons for opening the current file in the editor, search again, and cancel """ def __init__(self,scr,title = "File Find Dialog",fpat=".*",cpat="",recurse=False): """ takes the curses window to pop up over, title to display, will dynamically size to parent window """ max_y,max_x = scr.getmaxyx() pw = (max_x - 4) ph = ((max_y-7) // 2) cx = max_x // 2 y = 1 self.found_list = StreamSelectComponent("found",7,cx-(pw//2),y,pw,ph,"Found",where(os.getcwd(),fpat,cpat,recurse,scr)) y += ph self.preview = FileBrowseComponent("browse",8,cx-(pw//2),y,pw,ph,"Preview",None) y += ph self.start_dir = dialog.Prompt("dir",1,2,y,"Path: ",max_x-10,os.getcwd()) y += 1 self.recurse = dialog.Toggle("recurse",2,2,y,20,1,["Search Subdirs","Don't Search Subdirs"]) y += 1 self.file_name = dialog.Prompt("file",2,2,y,"File: ",max_x-10,fpat) y += 1 self.contains = dialog.Prompt("contains",3,2,y,"Contains:",max_x-13,cpat) y += 1 dialog.Dialog.__init__(self,scr,"FileFindDialog", max_y, max_x, [ dialog.Frame(title), self.found_list, self.preview, self.start_dir, self.recurse, self.file_name, self.contains, dialog.Button("search",4,2,y,"SEARCH",dialog.Component.CMP_KEY_NOP), dialog.Button("open",5,2+((max_x-4)//3),y,"OPEN",dialog.Component.CMP_KEY_OK), dialog.Button("cancel",6,2+(((max_x-4)//3)*2),y,"CANCEL",dialog.Component.CMP_KEY_CANCEL)]) def handle(self,ch): """ handles found file selection, populating the preview window, new searches, and opening a file """ focus_index = self.current focus_field = self.focus_list[self.current][1] ret_ch = dialog.Dialog.handle(self,ch) if ch in [keytab.KEYTAB_SPACE,keytab.KEYTAB_CR]: if focus_field == self.found_list: line = focus_field.getvalue().rstrip() fname = None number = 0 if ":" in line: fname,number,rest = line.split(":",2) else: fname = line self.preview.setfilename(fname,int(number)) else: values = self.getvalue() if values["search"]: (recurse,choices) = values["recurse"] self.found_list.setstream(where(values["dir"],values["file"],values["contains"],not recurse,self.getparent())) values["search"] = False self.setvalue(values) idx = 0 while idx < len(self.focus_list): if self.focus_list[idx][1] == self.found_list: self.current = idx break idx += 1 return ret_ch def filefind(scr, title = "File Find Dialog", fpat = ".*", cpat = "", recurse = False): """ wrapper function for finding files, returns either a (filename, line) tuple, or None if canceled """ d = FileFindDialog(scr,title,fpat,cpat,recurse) values = d.main() if "found" in values: line = values["found"].rstrip() number = 0 if ":" in line: fname,number,rest = line.split(":",2) else: fname = line return (fname,int(number)) else: return None def main(stdscr): """ test main driver for file find dialog """ try: d = FileFindDialog(stdscr) d.main() except Exception as e: log = open("file_find.log","w") print(str(e), file=log) print(traceback.format_exc(), file=log) if __name__ == '__main__': try: curses.wrapper(main) except Exception as e: log = open("file_find.log","w") print(str(e), file=log) print(traceback.format_exc(), file=log)
Functions
def contains(
fullpath, pattern, found)
test to see if the file referenced by fullpath contains pattern write result lines to file object found
def contains(fullpath, pattern, found): """ test to see if the file referenced by fullpath contains pattern write result lines to file object found """ try: line = 0 fl = open(fullpath, "r") inline = fl.readline(2048) while inline: sl = sanitize(inline) if re.search(pattern,sl): print("%s:%d:%s"%(fullpath,line,sl.rstrip()), file=found) inline = fl.readline(2048) line += 1 except Exception as e: print("%s:%d:ERROR %s"%(fullpath,line,str(e)), file=found)
def filefind(
scr, title='File Find Dialog', fpat='.*', cpat='', recurse=False)
wrapper function for finding files, returns either a (filename, line) tuple, or None if canceled
def filefind(scr, title = "File Find Dialog", fpat = ".*", cpat = "", recurse = False): """ wrapper function for finding files, returns either a (filename, line) tuple, or None if canceled """ d = FileFindDialog(scr,title,fpat,cpat,recurse) values = d.main() if "found" in values: line = values["found"].rstrip() number = 0 if ":" in line: fname,number,rest = line.split(":",2) else: fname = line return (fname,int(number)) else: return None
def main(
stdscr)
test main driver for file find dialog
def main(stdscr): """ test main driver for file find dialog """ try: d = FileFindDialog(stdscr) d.main() except Exception as e: log = open("file_find.log","w") print(str(e), file=log) print(traceback.format_exc(), file=log)
def sanitize(
text)
if a string has binary chunks replace them with hex return fixed up string
def sanitize( text ): """ if a string has binary chunks replace them with hex return fixed up string """ inbytes = array('B') inbytes.fromstring(text) hexchars = "0123456789ABCDEF" outtext = "" index = 0 for i in inbytes: if (i < 32 and (i not in [9,10,13])) or i > 127: hexout = hexchars[i//16] + hexchars[i%16] outtext = outtext + hexout else: outtext = outtext + text[index] index = index + 1 return outtext
def where(
path, fpat, cpat, recurse, scr)
recursively search for a pattern in files starting with path, files matchin re fpat, containing re cpat, if recurse == False only do one directory, if scr is non null then report status in a message dialog
def where( path, fpat, cpat, recurse, scr ): """ recursively search for a pattern in files starting with path, files matchin re fpat, containing re cpat, if recurse == False only do one directory, if scr is non null then report status in a message dialog""" found = tempfile.TemporaryFile(mode="w+") for (dirpath, dirnames, filenames) in os.walk(path): for f in filenames: if f[0] == ".": continue if f[-1] == "~": continue if f.endswith(".bak") or f.endswith(".pyc"): continue fullpath = os.path.join(dirpath,f) if re.search(r"\.svn",fullpath): continue try: if re.search(fpat,fullpath): if scr and cpat: message(scr,"Searching",fullpath,False) if cpat: contains(fullpath, cpat, found) else: print("%s"%(fullpath), file=found) except Exception as e: print("%s:0:ERROR:%s"%(fullpath,str(e)), file=found) if not recurse: break found.seek(0,0) return found
Classes
class FileFindDialog
dialog subclass that implements a file find dialog with a list of found files/lines preview window and fields for file pattern, contents pattern, recursive search, starting path, buttons for opening the current file in the editor, search again, and cancel
class FileFindDialog(dialog.Dialog): """ dialog subclass that implements a file find dialog with a list of found files/lines preview window and fields for file pattern, contents pattern, recursive search, starting path, buttons for opening the current file in the editor, search again, and cancel """ def __init__(self,scr,title = "File Find Dialog",fpat=".*",cpat="",recurse=False): """ takes the curses window to pop up over, title to display, will dynamically size to parent window """ max_y,max_x = scr.getmaxyx() pw = (max_x - 4) ph = ((max_y-7) // 2) cx = max_x // 2 y = 1 self.found_list = StreamSelectComponent("found",7,cx-(pw//2),y,pw,ph,"Found",where(os.getcwd(),fpat,cpat,recurse,scr)) y += ph self.preview = FileBrowseComponent("browse",8,cx-(pw//2),y,pw,ph,"Preview",None) y += ph self.start_dir = dialog.Prompt("dir",1,2,y,"Path: ",max_x-10,os.getcwd()) y += 1 self.recurse = dialog.Toggle("recurse",2,2,y,20,1,["Search Subdirs","Don't Search Subdirs"]) y += 1 self.file_name = dialog.Prompt("file",2,2,y,"File: ",max_x-10,fpat) y += 1 self.contains = dialog.Prompt("contains",3,2,y,"Contains:",max_x-13,cpat) y += 1 dialog.Dialog.__init__(self,scr,"FileFindDialog", max_y, max_x, [ dialog.Frame(title), self.found_list, self.preview, self.start_dir, self.recurse, self.file_name, self.contains, dialog.Button("search",4,2,y,"SEARCH",dialog.Component.CMP_KEY_NOP), dialog.Button("open",5,2+((max_x-4)//3),y,"OPEN",dialog.Component.CMP_KEY_OK), dialog.Button("cancel",6,2+(((max_x-4)//3)*2),y,"CANCEL",dialog.Component.CMP_KEY_CANCEL)]) def handle(self,ch): """ handles found file selection, populating the preview window, new searches, and opening a file """ focus_index = self.current focus_field = self.focus_list[self.current][1] ret_ch = dialog.Dialog.handle(self,ch) if ch in [keytab.KEYTAB_SPACE,keytab.KEYTAB_CR]: if focus_field == self.found_list: line = focus_field.getvalue().rstrip() fname = None number = 0 if ":" in line: fname,number,rest = line.split(":",2) else: fname = line self.preview.setfilename(fname,int(number)) else: values = self.getvalue() if values["search"]: (recurse,choices) = values["recurse"] self.found_list.setstream(where(values["dir"],values["file"],values["contains"],not recurse,self.getparent())) values["search"] = False self.setvalue(values) idx = 0 while idx < len(self.focus_list): if self.focus_list[idx][1] == self.found_list: self.current = idx break idx += 1 return ret_ch
Ancestors (in MRO)
- FileFindDialog
- ped_dialog.dialog.Dialog
- ped_dialog.dialog.Component
- builtins.object
Class variables
var CMP_KEY_CANCEL
var CMP_KEY_NOP
var CMP_KEY_OK
var history
Static methods
def __init__(
self, scr, title='File Find Dialog', fpat='.*', cpat='', recurse=False)
takes the curses window to pop up over, title to display, will dynamically size to parent window
def __init__(self,scr,title = "File Find Dialog",fpat=".*",cpat="",recurse=False): """ takes the curses window to pop up over, title to display, will dynamically size to parent window """ max_y,max_x = scr.getmaxyx() pw = (max_x - 4) ph = ((max_y-7) // 2) cx = max_x // 2 y = 1 self.found_list = StreamSelectComponent("found",7,cx-(pw//2),y,pw,ph,"Found",where(os.getcwd(),fpat,cpat,recurse,scr)) y += ph self.preview = FileBrowseComponent("browse",8,cx-(pw//2),y,pw,ph,"Preview",None) y += ph self.start_dir = dialog.Prompt("dir",1,2,y,"Path: ",max_x-10,os.getcwd()) y += 1 self.recurse = dialog.Toggle("recurse",2,2,y,20,1,["Search Subdirs","Don't Search Subdirs"]) y += 1 self.file_name = dialog.Prompt("file",2,2,y,"File: ",max_x-10,fpat) y += 1 self.contains = dialog.Prompt("contains",3,2,y,"Contains:",max_x-13,cpat) y += 1 dialog.Dialog.__init__(self,scr,"FileFindDialog", max_y, max_x, [ dialog.Frame(title), self.found_list, self.preview, self.start_dir, self.recurse, self.file_name, self.contains, dialog.Button("search",4,2,y,"SEARCH",dialog.Component.CMP_KEY_NOP), dialog.Button("open",5,2+((max_x-4)//3),y,"OPEN",dialog.Component.CMP_KEY_OK), dialog.Button("cancel",6,2+(((max_x-4)//3)*2),y,"CANCEL",dialog.Component.CMP_KEY_CANCEL)])
def btab(
self)
def btab(self): if self.focus_list: self.push_history(self.focus_list[self.current][1]) self.current -= 1 if self.current < 0: self.current = len(self.focus_list)-1
def focus(
self)
called when component is the focus
def focus(self): self.focus_list = [] for c in self.children: self.pop_history(c) if c.getorder() > 0: self.focus_list.append((c.getorder(),c)) if not self.focus_list: self.current = 0 return self.focus_list.sort(key=lambda x: x[0]) self.current = 0
def getname(
self)
get the name of this component
def getname(self): """ get the name of this component """ return self.name
def getorder(
self)
get this component's tab order number
def getorder(self): """ get this component's tab order number """ return self.order
def getparent(
self)
get this component's curses target window
def getparent(self): """ get this component's curses target window """ return self.parent
def getvalue(
self)
return the current value of the component
def getvalue(self): value = {} for c in self.children: if c.getname(): value[c.getname()] = c.getvalue() return value
def goto(
self, component)
move focus to this component
def goto(self, component): """ move focus to this component """ for i in range(0,len(self.focus_list)): if self.focus_list[i][1] == component: self.current = i return True return False
def handle(
self, ch)
handles found file selection, populating the preview window, new searches, and opening a file
def handle(self,ch): """ handles found file selection, populating the preview window, new searches, and opening a file """ focus_index = self.current focus_field = self.focus_list[self.current][1] ret_ch = dialog.Dialog.handle(self,ch) if ch in [keytab.KEYTAB_SPACE,keytab.KEYTAB_CR]: if focus_field == self.found_list: line = focus_field.getvalue().rstrip() fname = None number = 0 if ":" in line: fname,number,rest = line.split(":",2) else: fname = line self.preview.setfilename(fname,int(number)) else: values = self.getvalue() if values["search"]: (recurse,choices) = values["recurse"] self.found_list.setstream(where(values["dir"],values["file"],values["contains"],not recurse,self.getparent())) values["search"] = False self.setvalue(values) idx = 0 while idx < len(self.focus_list): if self.focus_list[idx][1] == self.found_list: self.current = idx break idx += 1 return ret_ch
def handle_mouse(
self)
def handle_mouse(self): if self.focus_list and self.win: try: mid, mx, my, mz, mtype = curses.getmouse() by,bx = self.win.getbegyx() oy = my - by ox = mx - bx for i in range(0,len(self.focus_list)): c = self.focus_list[i][1] ret = c.mouse_event(ox,oy,mtype) if ret >= 0: self.current = i return ret else: return -1 except: return -1
def isempty(
self)
test if the component entry is empty
def isempty(self): """ test if the component entry is empty """ return False
def main(
self, blocking=True, force=False, ch_in=None)
def main(self,blocking = True,force=False,ch_in = None): curses.mousemask( curses.BUTTON1_PRESSED| curses.BUTTON1_RELEASED| curses.BUTTON1_CLICKED) self.win.nodelay(1) self.win.notimeout(0) self.win.timeout(0) old_cursor = curses.curs_set(1) while (1): if (not keymap.keypending(self.win)) or force: self.render() if not ch_in: ch = self.handle(keymap.get_keyseq(self.win,keymap.getch(self.win))) else: ch = self.handle(ch_in) if blocking: if ch == Component.CMP_KEY_CANCEL: curses.curs_set(old_cursor) return {} elif ch == Component.CMP_KEY_OK: curses.curs_set(old_cursor) return self.getvalue() else: if ch == Component.CMP_KEY_CANCEL: curses.curs_set(old_cursor) return (ch, {}) else: curses.curs_set(old_cursor) return (ch, self.getvalue())
def mouse_event(
self, ox, oy, mtype)
handle mouse events return key value or -1 for not handled
def mouse_event(self, ox, oy, mtype): """ handle mouse events return key value or -1 for not handled """ return -1
def pop_history(
self, child)
def pop_history( self, child ): if not self.enable_history: return if not issubclass(child.__class__, Prompt): return if self.getname() and child.getname() and child.getorder() >= 0: key = (self.getname(), child.getname()) if key in Dialog.history: hist = Dialog.history[key] self.hist_idx += 1 if self.hist_idx > len(hist): self.hist_idx = 0 child.setvalue(hist[-self.hist_idx])
def push_history(
self, child)
def push_history( self, child ): if not self.enable_history: return if not issubclass(child.__class__, Prompt): return if self.getname() and child.getname() and child.getorder() >= 0 and not child.isempty(): key = (self.getname(), child.getname()) if key in Dialog.history: if Dialog.history[key][-1] != child.getvalue(): Dialog.history[key].append(child.getvalue()) else: Dialog.history[key] = [child.getvalue()]
def render(
self)
render the component use parent as target
def render(self): self.win.leaveok(1) for c in self.children: if not self.focus_list or self.focus_list[self.current][1] != c: c.render() self.win.leaveok(0) if self.focus_list: self.focus_list[self.current][1].focus() self.focus_list[self.current][1].render() self.win.refresh()
def resize(
self)
def resize(self): pass
def set_history(
self, state)
def set_history( self, state ): self.enable_history = state
def setparent(
self, parent)
set the parent curses target window
def setparent(self,parent): """ set the parent curses target window """ self.parent = parent
def setpos(
self, x, y)
set the position of this component
def setpos(self, x, y ): """ set the position of this component """ self.x = x self.y = y
def setsize(
self, height, width)
set the width of this component
def setsize(self, height, width ): """ set the width of this component """ self.height = height self.width = width
def setvalue(
self, value)
set the components value, may be tuple or other data structure
def setvalue(self, value): for c in self.children: if c.getname() in value: c.setvalue(value[c.getname()]) self.push_history(c)
def tab(
self)
def tab(self): if self.focus_list: self.push_history(self.focus_list[self.current][1]) self.current += 1 if self.current >= len(self.focus_list): self.current = 0
Instance variables
var contains
var file_name
var found_list
var preview
var recurse
var start_dir