home *** CD-ROM | disk | FTP | other *** search
/ Clickx 115 / Clickx 115.iso / software / tools / windows / tails-i386-0.16.iso / live / filesystem.squashfs / usr / share / system-config-printer / timedops.py < prev    next >
Encoding:
Python Source  |  2010-09-28  |  7.6 KB  |  232 lines

  1. #!/usr/bin/env python
  2.  
  3. ## Copyright (C) 2008, 2009, 2010 Red Hat, Inc.
  4. ## Authors:
  5. ##  Tim Waugh <twaugh@redhat.com>
  6.  
  7. ## This program is free software; you can redistribute it and/or modify
  8. ## it under the terms of the GNU General Public License as published by
  9. ## the Free Software Foundation; either version 2 of the License, or
  10. ## (at your option) any later version.
  11.  
  12. ## This program is distributed in the hope that it will be useful,
  13. ## but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. ## GNU General Public License for more details.
  16.  
  17. ## You should have received a copy of the GNU General Public License
  18. ## along with this program; if not, write to the Free Software
  19. ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  
  21. import gobject
  22. import gtk
  23. import subprocess
  24. import threading
  25. from gettext import gettext as _
  26. from debug import *
  27.  
  28. class OperationCanceled(RuntimeError):
  29.     pass
  30.  
  31. class Timed:
  32.     def run (self):
  33.         pass
  34.  
  35.     def cancel (self):
  36.         return False
  37.  
  38. class TimedSubprocess(Timed):
  39.     def __init__ (self, timeout=60000, parent=None, show_dialog=True,
  40.                   **args):
  41.         self.subp = subprocess.Popen (**args)
  42.         self.output = dict()
  43.         self.io_source = []
  44.         self.watchers = 2
  45.         self.timeout = timeout
  46.         self.parent = parent
  47.         self.show_dialog = show_dialog
  48.         for f in [self.subp.stdout, self.subp.stderr]:
  49.             if f != None:
  50.                 source = gobject.io_add_watch (f,
  51.                                                gobject.IO_IN |
  52.                                                gobject.IO_HUP |
  53.                                                gobject.IO_ERR,
  54.                                                self.watcher)
  55.                 self.io_source.append (source)
  56.  
  57.         self.wait_window = None
  58.  
  59.     def run (self):
  60.         if self.show_dialog:
  61.             self.wait_source = gobject.timeout_add_seconds (
  62.                 1,
  63.                 self.show_wait_window)
  64.  
  65.         self.timeout_source = gobject.timeout_add (self.timeout,
  66.                                                    self.do_timeout)
  67.         gtk.main ()
  68.         gobject.source_remove (self.timeout_source)
  69.         if self.show_dialog:
  70.             gobject.source_remove (self.wait_source)
  71.         for source in self.io_source:
  72.             gobject.source_remove (source)
  73.         if self.wait_window != None:
  74.             self.wait_window.destroy ()
  75.         return (self.output.get (self.subp.stdout, '').split ('\n'),
  76.                 self.output.get (self.subp.stderr, '').split ('\n'),
  77.                 self.subp.poll ())
  78.  
  79.     def do_timeout (self):
  80.         gtk.main_quit ()
  81.         return False
  82.  
  83.     def watcher (self, source, condition):
  84.         if condition & gobject.IO_IN:
  85.             buffer = self.output.get (source, '')
  86.             buffer += source.read ()
  87.             self.output[source] = buffer
  88.  
  89.         if condition & gobject.IO_HUP:
  90.             self.watchers -= 1
  91.             if self.watchers == 0:
  92.                 gtk.main_quit ()
  93.                 return False
  94.  
  95.         return True
  96.  
  97.     def show_wait_window (self):
  98.         gtk.gdk.threads_enter ()
  99.         wait = gtk.MessageDialog (self.parent,
  100.                                   gtk.DIALOG_MODAL |
  101.                                   gtk.DIALOG_DESTROY_WITH_PARENT,
  102.                                   gtk.MESSAGE_INFO,
  103.                                   gtk.BUTTONS_CANCEL,
  104.                                   _("Please wait"))
  105.         wait.connect ("delete_event", lambda *args: False)
  106.         wait.connect ("response", self.wait_window_response)
  107.         if self.parent:
  108.             wait.set_transient_for (self.parent)
  109.         wait.set_position (gtk.WIN_POS_CENTER_ON_PARENT)
  110.         wait.format_secondary_text (_("Gathering information"))
  111.         wait.show_all ()
  112.         self.wait_window = wait
  113.         gtk.gdk.threads_leave ()
  114.         return False
  115.  
  116.     def wait_window_response (self, dialog, response):
  117.         if response == gtk.RESPONSE_CANCEL:
  118.             self.cancel ()
  119.  
  120.     def cancel (self):
  121.         if self.watchers > 0:
  122.             debugprint ("Command canceled")
  123.             gtk.main_quit ()
  124.             self.watchers = 0
  125.  
  126.         return False
  127.  
  128. class OperationThread(threading.Thread):
  129.     def __init__ (self, target=None, args=(), kwargs={}):
  130.         threading.Thread.__init__ (self)
  131.         self.setDaemon (True)
  132.         self.target = target
  133.         self.args = args
  134.         self.kwargs = kwargs
  135.         self.exception = None
  136.         self.result = None
  137.  
  138.     def run (self):
  139.         try:
  140.             debugprint ("Calling %s" % self.target)
  141.             self.result = self.target (*self.args, **self.kwargs)
  142.             debugprint ("Done")
  143.         except Exception, e:
  144.             debugprint ("Caught exception %s" % e)
  145.             self.exception = e
  146.  
  147.     def collect_result (self):
  148.         if self.isAlive ():
  149.             # We've been canceled.
  150.             raise OperationCanceled()
  151.  
  152.         if self.exception:
  153.             raise self.exception
  154.  
  155.         return self.result
  156.  
  157. class TimedOperation(Timed):
  158.     def __init__ (self, target, args=(), kwargs={}, parent=None,
  159.                   show_dialog=False, callback=None, context=None):
  160.         self.wait_window = None
  161.         self.parent = parent
  162.         self.show_dialog = show_dialog
  163.         self.callback = callback
  164.         self.context = context
  165.         self.thread = OperationThread (target=target,
  166.                                        args=args,
  167.                                        kwargs=kwargs)
  168.         self.thread.start ()
  169.  
  170.         self.use_callback = callback != None
  171.         if self.use_callback:
  172.             self.timeout_source = gobject.timeout_add (50, self._check_thread)
  173.  
  174.     def run (self):
  175.         if self.use_callback:
  176.             raise RuntimeError
  177.  
  178.         if self.show_dialog:
  179.             wait = gtk.MessageDialog (self.parent,
  180.                                       gtk.DIALOG_MODAL |
  181.                                       gtk.DIALOG_DESTROY_WITH_PARENT,
  182.                                       gtk.MESSAGE_INFO,
  183.                                       gtk.BUTTONS_CANCEL,
  184.                                       _("Please wait"))
  185.             wait.connect ("delete_event", lambda *args: False)
  186.             wait.connect ("response", self._wait_window_response)
  187.             if self.parent:
  188.                 wait.set_transient_for (self.parent)
  189.  
  190.             wait.set_position (gtk.WIN_POS_CENTER_ON_PARENT)
  191.             wait.format_secondary_text (_("Gathering information"))
  192.             wait.show_all ()
  193.  
  194.         self.timeout_source = gobject.timeout_add (50, self._check_thread)
  195.         gtk.main ()
  196.         gobject.source_remove (self.timeout_source)
  197.         if self.show_dialog:
  198.             wait.destroy ()
  199.  
  200.         return self.thread.collect_result ()
  201.  
  202.     def _check_thread (self):
  203.         if self.thread.isAlive ():
  204.             # Thread still running.
  205.             return True
  206.  
  207.         # Thread has finished.  Stop the sub-loop or trigger callback.
  208.         if self.use_callback:
  209.             if self.callback != None:
  210.                 if self.context != None:
  211.                     self.callback (self.thread.result, self.thread.exception,
  212.                                    self.context)
  213.                 else:
  214.                     self.callback (self.thread.result, self.thread.exception)
  215.         else:
  216.             gtk.main_quit ()
  217.  
  218.         return False
  219.  
  220.     def _wait_window_response (self, dialog, response):
  221.         if response == gtk.RESPONSE_CANCEL:
  222.             self.cancel ()
  223.  
  224.     def cancel (self):
  225.         debugprint ("Command canceled")
  226.         if self.use_callback:
  227.             self.callback = None
  228.         else:
  229.             gtk.main_quit ()
  230.  
  231.         return False
  232.