Package node_manager_fkie :: Package editor :: Module text_search_thread
[frames] | no frames]

Source Code for Module node_manager_fkie.editor.text_search_thread

  1  # Software License Agreement (BSD License) 
  2  # 
  3  # Copyright (c) 2012, Fraunhofer FKIE/US, Alexander Tiderko 
  4  # All rights reserved. 
  5  # 
  6  # Redistribution and use in source and binary forms, with or without 
  7  # modification, are permitted provided that the following conditions 
  8  # are met: 
  9  # 
 10  #  * Redistributions of source code must retain the above copyright 
 11  #    notice, this list of conditions and the following disclaimer. 
 12  #  * Redistributions in binary form must reproduce the above 
 13  #    copyright notice, this list of conditions and the following 
 14  #    disclaimer in the documentation and/or other materials provided 
 15  #    with the distribution. 
 16  #  * Neither the name of Fraunhofer nor the names of its 
 17  #    contributors may be used to endorse or promote products derived 
 18  #    from this software without specific prior written permission. 
 19  # 
 20  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 21  # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 22  # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
 23  # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
 24  # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
 25  # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
 26  # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
 27  # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
 28  # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
 29  # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
 30  # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
 31  # POSSIBILITY OF SUCH DAMAGE. 
 32   
 33  from python_qt_binding.QtCore import QObject, Signal 
 34  from python_qt_binding.QtCore import QRegExp, QFile 
 35  import os 
 36  import rospy 
 37  import threading 
 38   
 39  import node_manager_fkie as nm 
 40   
 41  from .parser_functions import interpret_path 
 42   
 43   
44 -class TextSearchThread(QObject, threading.Thread):
45 ''' 46 A thread to search recursive for a text in files. 47 ''' 48 search_result_signal = Signal(str, bool, str, int, int, str) 49 ''' @ivar: A signal emitted after search_threaded was started. 50 (search text, found or not, file, position in text, line number, line text) 51 for each result a signal will be emitted. 52 ''' 53 warning_signal = Signal(str) 54
55 - def __init__(self, search_text, path, is_regex=False, path_text={}, recursive=False):
56 ''' 57 :param search_text: text to search for 58 :type search_text: str 59 :param path: initial file path 60 :type path: str 61 .param is_regex: is the search_text a regular expressions 62 :type is_regex: bool 63 ''' 64 QObject.__init__(self) 65 threading.Thread.__init__(self) 66 self._search_text = search_text 67 self._path = path 68 self._path_text = path_text 69 self._recursive = recursive 70 self._isrunning = True 71 self.setDaemon(True)
72
73 - def stop(self):
74 self._isrunning = False
75
76 - def run(self):
77 ''' 78 ''' 79 try: 80 self.search(self._search_text, self._path, self._recursive) 81 except: 82 import traceback 83 # print traceback.print_exc() 84 formatted_lines = traceback.format_exc(1).splitlines() 85 rospy.logwarn("Error while search for '%s' in '%s': %s" % (self._search_text, self._path, formatted_lines[-1])) 86 self.warning_signal.emit(formatted_lines[-1]) 87 finally: 88 if self._isrunning: 89 self.search_result_signal.emit(self._search_text, False, '', -1, -1, '')
90
91 - def search(self, search_text, path, recursive=False):
92 ''' 93 Searches for given text in this document and all included files. 94 @param search_text: text to find 95 @type search_text: C{str} 96 @return: the list with all files contain the text 97 @rtype: C{[str, ...]} 98 ''' 99 data = self._get_text(path) 100 pos = data.find(search_text) 101 slen = len(search_text) 102 while pos != -1 and self._isrunning: 103 if self._isrunning: 104 self.search_result_signal.emit(search_text, True, path, pos, data.count('\n', 0, pos) + 1, self._strip_text(data, pos)) 105 pos += slen 106 pos = data.find(search_text, pos) 107 if self._isrunning: 108 inc_files = self._included_files(path) 109 for incf in inc_files: 110 if not self._isrunning: 111 break 112 if recursive: 113 self.search(search_text, incf, recursive)
114
115 - def _get_text(self, path):
116 if path in self._path_text: 117 return self._path_text[path] 118 with open(path, 'r') as f: 119 data = f.read() 120 return data 121 return ''
122
123 - def _included_files(self, path):
124 ''' 125 Returns all included files in the given file. 126 ''' 127 result = [] 128 with open(path, 'r') as f: 129 data = f.read() 130 reg = QRegExp("=[\s\t]*\".*\"") 131 reg.setMinimal(True) 132 pos = reg.indexIn(data) 133 while pos != -1 and self._isrunning: 134 try: 135 pp = interpret_path(reg.cap(0).strip('"')) 136 f = QFile(pp) 137 ext = os.path.splitext(pp) 138 if f.exists() and ext[1] in nm.settings().SEARCH_IN_EXT: 139 result.append(pp) 140 except Exception as exp: 141 parsed_text = pp 142 try: 143 parsed_text = reg.cap(0).strip('"') 144 except: 145 pass 146 self.warning_signal.emit("Error while parse '%s': %s" % (parsed_text, exp)) 147 pos += reg.matchedLength() 148 pos = reg.indexIn(data, pos) 149 return result
150
151 - def _strip_text(self, data, pos):
152 start = pos 153 end = pos 154 while start > 0 and data[start - 1] not in ['\n', '\0', '\r']: 155 start -= 1 156 while end < len(data) and data[end] not in ['\n', '\0', '\r']: 157 end += 1 158 return data[start:end].strip()
159