Package node_manager_fkie :: Module progress_queue
[frames] | no frames]

Source Code for Module node_manager_fkie.progress_queue

  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  import time 
 34  import socket 
 35  import threading 
 36  import xmlrpclib 
 37  import random 
 38  from PySide import QtCore 
 39  from PySide import QtGui 
 40   
 41  import rospy 
 42   
 43  import node_manager_fkie as nm 
 44  from detailed_msg_box import WarningMessageBox, DetailedError 
 45   
46 -class InteractionNeededError(Exception):
47 ''' 48 request: AuthenticationRequest 49 '''
50 - def __init__(self, request, method, args):
51 Exception.__init__(self) 52 self.method = method 53 self.request = request 54 self.args = args
55
56 - def __str__(self):
57 return "InteractionNeededError"
58 59
60 -class ProgressQueue(QtCore.QObject):
61
62 - def __init__(self, progress_frame, progress_bar, progress_cancel_button):
63 self.__progress_queue = [] 64 self._progress_frame = progress_frame 65 self._progress_bar = progress_bar 66 self._progress_cancel_button = progress_cancel_button 67 progress_frame.setVisible(False) 68 progress_cancel_button.clicked.connect(self._on_progress_canceled)
69
70 - def stop(self):
71 try: 72 val = self._progress_bar.value() 73 if val < len(self.__progress_queue): 74 print " Shutdown progress queue..." 75 thread = self.__progress_queue[val] 76 self.__progress_queue = [] 77 thread.join(3) 78 print " Progress queue is off!" 79 except: 80 pass
81 82
83 - def add2queue(self, id, descr, target=None, args=()):
84 pt = ProgressThread(id, descr, target, args) 85 pt.finished_signal.connect(self._progress_thread_finished) 86 pt.error_signal.connect(self._progress_thread_error) 87 pt.request_interact_signal.connect(self._on_request_interact) 88 self.__progress_queue.append(pt) 89 self._progress_bar.setMaximum(len(self.__progress_queue))
90
91 - def start(self):
92 if not self._progress_frame.isVisible() and self.__progress_queue: 93 self._progress_frame.setVisible(True) 94 self._progress_bar.setValue(0) 95 self.__progress_queue[0].start()
96
97 - def count(self):
98 return len(self.__progress_queue)
99
100 - def _progress_thread_finished(self, id):
101 try: 102 #'print "PG finished", id 103 val = self._progress_bar.value() 104 self.__progress_queue[val+1].start() 105 self._progress_bar.setValue(val+1) 106 #'print "PG finished ok", id 107 except: 108 #'print "PG finished err", id 109 for thread in self.__progress_queue: 110 thread.join(1) 111 self._progress_frame.setVisible(False) 112 #'print "PG finished delete all..." 113 self.__progress_queue = []
114 #'print "PG finished delete all ok" 115
116 - def _progress_thread_error(self, id, title, msg, detailed_msg):
117 res = WarningMessageBox(QtGui.QMessageBox.Warning, title, msg, detailed_msg, 118 buttons=(QtGui.QMessageBox.Ignore|QtGui.QMessageBox.Abort) ).exec_() 119 if res == QtGui.QMessageBox.Abort: 120 self.__progress_queue = [] 121 self._progress_frame.setVisible(False) 122 else: 123 self._progress_thread_finished(id)
124
125 - def _on_progress_canceled(self):
126 try: 127 # self.__progress_queue[self._progress_bar.value()].wait() 128 self.__progress_queue = [] 129 self._progress_frame.setVisible(False) 130 except: 131 import traceback 132 print traceback.format_exc()
133
134 - def _on_request_interact(self, id, descr, req):
135 if isinstance(req.request, nm.AuthenticationRequest): 136 res, user, pw = nm.ssh()._requestPW(req.request.user, req.request.host) 137 if not res: 138 self._on_progress_canceled() 139 return 140 pt = ProgressThread(id, descr, req.method, (req.args+(user, pw))) 141 pt.finished_signal.connect(self._progress_thread_finished) 142 pt.error_signal.connect(self._progress_thread_error) 143 pt.request_interact_signal.connect(self._on_request_interact) 144 pt.start() 145 elif isinstance(req.request, nm.ScreenSelectionRequest): 146 from select_dialog import SelectDialog 147 items = SelectDialog.getValue('Show screen', req.request.choices.keys(), False) 148 if not items: 149 self._progress_thread_finished(id) 150 return 151 res = [req.request.choices[i] for i in items] 152 pt = ProgressThread(id, descr, req.method, (req.args+(res,))) 153 pt.finished_signal.connect(self._progress_thread_finished) 154 pt.error_signal.connect(self._progress_thread_error) 155 pt.request_interact_signal.connect(self._on_request_interact) 156 pt.start()
157 158 159
160 -class ProgressThread(QtCore.QObject, threading.Thread):
161 ''' 162 A thread to execute a method in a thread. 163 ''' 164 finished_signal = QtCore.Signal(str) 165 ''' 166 @ivar: finished_signal is a signal, which is emitted, if the thread is finished. 167 ''' 168 169 error_signal = QtCore.Signal(str, str, str, str) 170 ''' 171 @ivar: error_signal is a signal (id, title, error message, detailed error message), which is emitted, 172 if an error while run of the thread was occurred. 173 ''' 174 175 request_interact_signal = QtCore.Signal(str, str, InteractionNeededError) 176
177 - def __init__(self, id, descr='', target=None, args=()):
178 QtCore.QObject.__init__(self) 179 threading.Thread.__init__(self) 180 self._id = id 181 self._descr = descr 182 self._target = target 183 self._args = args 184 self.setDaemon(True)
185
186 - def run(self):
187 ''' 188 ''' 189 try: 190 if not self._target is None: 191 #'print "PG call " 192 #'print " .. ", self._target 193 #'print " -- args:", self._args 194 self._target(*self._args) 195 #'print "PG call finished" 196 self.finished_signal.emit(self._id) 197 else: 198 self.error_signal.emit(self._id, 'No target specified') 199 except InteractionNeededError as e: 200 self.request_interact_signal.emit(self._id, self._descr, e) 201 except DetailedError as e: 202 self.error_signal.emit(self._id, e.title, e.value, e.detailed_text) 203 except: 204 import traceback 205 # print traceback.print_exc() 206 formatted_lines = traceback.format_exc().splitlines() 207 last_line = formatted_lines[-1] 208 index = 1 209 while not last_line and len(formatted_lines) > index: 210 index += 1 211 last_line = formatted_lines[-index] 212 rospy.logwarn("%s failed:\n\t%s", str(self._descr), last_line) 213 self.error_signal.emit(self._id, 'Progress Job Error', str(self._descr)+" failed:\n"+last_line, traceback.format_exc())
214