diff --git a/DrPrintBackend.py b/DrPrintBackend.py index dce23a7..239e0d0 100644 --- a/DrPrintBackend.py +++ b/DrPrintBackend.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- ## Some useful function to help DrPrint to -import paramiko, gobject, select, time, re +import paramiko, gobject, select, time, re, os class PrintingError(Exception): @@ -14,8 +14,23 @@ class PrintingError(Exception): class Backend(gobject.GObject): + __gsignals__ = { + 'transfer-progress': (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, + (gobject.TYPE_INT, + gobject.TYPE_INT)), + + 'transfer-started': (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, + ()), + + 'transfer-finished': (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, + ()), + } + def __init__(self): - super(Backend, self).__init__() + gobject.GObject.__init__(self) def get_queue(self, printer, remote_host, username, password): """ @@ -66,14 +81,14 @@ class Backend(gobject.GObject): return jobs - + def cancel_transfer(self, widget): + self.__abort_transfer = True def send_print(self, printer, username, password, page_per_page, filename, page_range, copies, orientation, sides, remote_host): + + self.__abort_transfer = False - # Get printer name - print "Selected printer: %s" % printer - # Get connection try: client = paramiko.SSHClient() @@ -94,8 +109,6 @@ class Backend(gobject.GObject): t = client.get_transport() sftp = paramiko.SFTPClient.from_transport(t) - print "Printing %s" % filename - # Questo è inevitabile.. :) cmd = "lpr -P%s " % printer @@ -130,24 +143,39 @@ class Backend(gobject.GObject): cmd = cmd + "%s" % cmd_opts + " /tmp/drprint_tmp_%s" % username try: - attr = sftp.put(filename, "/tmp/drprint_tmp_%s" % username) + self.emit('transfer-started') + buf_size = 4096 # 4 Kb + open_file = sftp.file("/tmp/drprint_tmp_%s" % username, "w") + bytes_read = 0 + file_size = os.path.getsize(filename) + with open(filename, "r") as local_handle: + buf = None + while(buf != ""): + buf = local_handle.read(buf_size) + bytes_read = bytes_read + len(buf) + if self.__abort_transfer: + return self.__abort_transfer + open_file.write(buf) + self.emit('transfer-progress', bytes_read, file_size) except OSError: raise PrintingError('Errore nel trasferimento del file') else: - print "File trasferito, dimensione: %d bytes" % attr.st_size + pass + + self.emit('transfer-finished') # Apriamo la sessione. chan = t.open_session() # Diamo il comando sul canale - print "Eseguo %s" % cmd chan.exec_command(cmd) - exit_status = chan.recv_exit_status() + chan.close() if exit_status == 0: sftp.remove("/tmp/drprint_tmp_%s" % username) - print "Printed %s on %s (exit status = %d)" % (filename, printer, exit_status) if exit_status != 0: raise PrintingError('Il comando <b>lpr</b> non e\' andato a buon fine (Exit status = %d)' % exit_status) + + return self.__abort_transfer diff --git a/DrPrintGui/Dialogs.py b/DrPrintGui/Dialogs.py index cf4f352..d6b4787 100644 --- a/DrPrintGui/Dialogs.py +++ b/DrPrintGui/Dialogs.py @@ -1,4 +1,4 @@ -import gtk, pygtk +import gtk, pygtk, gobject class Dialog(gtk.MessageDialog): @@ -72,3 +72,48 @@ class MessageDialog(Dialog): self.format_secondary_markup(text) +class ProgressDialog(gtk.Dialog): + + __gsignals__ = { + 'transfer-cancelled': (gobject.SIGNAL_RUN_LAST, + gobject.TYPE_NONE, ()) + } + + def __init__(self, filename): + + gtk.Dialog.__init__(self, + title = "Trasferimento file in corso...", + buttons = None) + self.__progress_bar = gtk.ProgressBar() + self.__progress_bar.set_fraction(0) + self.set_border_width(5) + + self.get_content_area().set_spacing(5) + + filename = filename.split("/")[-1] + text = "Trasferimento del file %s \n sul server remoto in corso..." % filename + label = gtk.Label(text) + self.get_content_area().pack_start(label, 5) + self.get_content_area().pack_start(self.__progress_bar, 5) + label.show() + self.__progress_bar.show() + + cancel_button = gtk.Button("Annulla") + self.get_content_area().pack_start(cancel_button, 5) + cancel_button.show() + + cancel_button.connect("clicked", self.cancel) + + def cancel(self, widget): + self.emit('transfer-cancelled') + self.hide() + + def set_fraction(self, fraction): + self.__progress_bar.set_fraction(fraction) + while gtk.events_pending(): + gtk.main_iteration() + + + + + diff --git a/DrPrintGui/MainWin.py b/DrPrintGui/MainWin.py index 167c980..3a6e5ed 100644 --- a/DrPrintGui/MainWin.py +++ b/DrPrintGui/MainWin.py @@ -13,7 +13,7 @@ import sys from Input import AuthBlock, PrinterSettingsBlock, PrintButton, LeftAlignedLabel, \ PageRangeBlock, OrientationSelect, SidesSelect, QueueButton -from Dialogs import ErrorDialog, MessageDialog, InfoDialog, QueueDialog +from Dialogs import ErrorDialog, MessageDialog, InfoDialog, QueueDialog, ProgressDialog from DrPrintBackend import PrintingError class MainWin(gtk.Window): @@ -27,7 +27,7 @@ class MainWin(gtk.Window): gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL) - self.set_title = "DrPrint 0.8" + self.set_title = "DrPrint 0.9" self.set_border_width(10) self.default_spacing = 5 @@ -210,7 +210,13 @@ Se vuoi continuare premi OK") if resp == gtk.RESPONSE_OK: try: - self.backend.send_print(printer = printer, + progress_dialog = ProgressDialog(filename) + self.backend.connect('transfer-started', lambda widget : progress_dialog.show()) + self.backend.connect('transfer-progress', + lambda widget, a, b : progress_dialog.set_fraction(a * 1.0 / b)) + self.backend.connect('transfer-finished', lambda widget : progress_dialog.hide()) + progress_dialog.connect('transfer-cancelled', self.backend.cancel_transfer) + result = self.backend.send_print(printer = printer, username = username, password = password, filename = filename, @@ -227,11 +233,12 @@ Se vuoi continuare premi OK") dialog.run() dialog.destroy() else: - dialog = InfoDialog("Stampa effettuata", - "Il file %s è stato stampato correttamente sulla stampante <b>%s</b>." - % (filename, printer)) - dialog.run() - dialog.destroy() + if not result: + dialog = InfoDialog("Stampa effettuata", + "Il file %s è stato stampato correttamente sulla stampante <b>%s</b>." + % (filename, printer)) + dialog.run() + dialog.destroy() self.print_button.set_state("idle") else: