From d360a0e05efa2a126abf141c3fc63f3600d20b94 Mon Sep 17 00:00:00 2001 From: Leonardo Date: Thu, 10 Jun 2010 17:50:20 +0200 Subject: [PATCH] Nuova versione (bump a 0.9) , release candidate per la gestione delle code di stampa. --- DrPrintBackend.py | 44 ++++++++++++++++++++++++++++++--- DrPrintGui/Dialogs.py | 22 +++++++++++++++++ DrPrintGui/Input.py | 67 ++++++++++++++++++++++++++++++++++++++++++--------- DrPrintGui/MainWin.py | 59 ++++++++++++++++++++++++++++++++++++++++----- debian/changelog | 6 +++++ 5 files changed, 177 insertions(+), 21 deletions(-) diff --git a/DrPrintBackend.py b/DrPrintBackend.py index 867396e..c1cedbf 100644 --- a/DrPrintBackend.py +++ b/DrPrintBackend.py @@ -1,7 +1,7 @@ ## Some useful function to help DrPrint to # -*- coding: utf-8 -*- -import paramiko, gobject, select, time +import paramiko, gobject, select, time, re class PrintingError(Exception): @@ -11,13 +11,51 @@ class PrintingError(Exception): def __str__(self): return repr(self.value) + class Backend(gobject.GObject): def __init__(self): super(Backend, self).__init__() + def get_queue(self, printer, remote_host, username, password): - def send_print(self, printer, username, password, page_per_page, filename, page_range, copies, orientation, sides): + try: + client = paramiko.SSHClient() + client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + except: + raise RuntimeError('Impossibile inizializzare paramiko') + + try: + client.connect(remote_host, + port = 22, + username = username, + password = password) + except: + raise RuntimeError('Impossibile connettersi a %s' % remote_host) + + stdin, stdout, stderr = client.exec_command("lpq -P%s" % printer) + output = stdout.read() + + # Parse output + jobs = [] + for line in re.findall(r"(\d+)\w*\s+(\w+)\s+(\d+)\s+(.+)\s+(\d+) bytes", + output): + job = { + 'position': int(line[0]), + 'user': line[1], + 'id': line[2], + 'filename': line[3].strip(), + 'size': line[4] + } + jobs.append(job) + return jobs + + + + + def send_print(self, printer, username, password, page_per_page, + filename, page_range, copies, orientation, sides, remote_host): + # Get printer name print "Selected printer: %s" % printer @@ -29,7 +67,7 @@ class Backend(gobject.GObject): raise PrintingError('Impossibili inizializzare paramiko') try: - client.connect('ssh.dm.unipi.it', + client.connect(remote_host, port=22, username=username, password=password) diff --git a/DrPrintGui/Dialogs.py b/DrPrintGui/Dialogs.py index d37ea98..cf4f352 100644 --- a/DrPrintGui/Dialogs.py +++ b/DrPrintGui/Dialogs.py @@ -23,6 +23,28 @@ class ErrorDialog(Dialog): self.set_markup(error) self.format_secondary_markup(message) +class QueueDialog(Dialog): + + def __init__(self, jobs, printer): + + Dialog.__init__(self, + buttons = gtk.BUTTONS_OK, + mtype = gtk.MESSAGE_INFO + ) + + if len(jobs) == 0: + self.set_markup("Non ci sono lavori in coda su %s." % printer) + else: + self.set_markup("Ci sono %d lavori in coda su %s:" % (len(jobs), printer)) + + # Lista dei lavori + markup = "" + for job in jobs: + markup += "%d) %s sta stampando %s\n" % (job['position'], job['user'], + job['filename']) + self.format_secondary_markup (markup) + + class InfoDialog(Dialog): def __init__(self, error, message): diff --git a/DrPrintGui/Input.py b/DrPrintGui/Input.py index 96954b9..c579573 100644 --- a/DrPrintGui/Input.py +++ b/DrPrintGui/Input.py @@ -39,8 +39,8 @@ class UsernameField(gtk.Entry): if user is None: self.set_text( os.getenv("USER") ) else: - self.set_text(user) - + self.set_text(user) + class PasswordField(gtk.Entry): @@ -51,9 +51,26 @@ class PasswordField(gtk.Entry): self.set_text ("") self.set_visibility(False) +class RemoteHostComboBox(gtk.HBox): + + def __init__(self, default_hosts): + + gtk.HBox.__init__(self) + self.combobox = gtk.combo_box_new_text() + for remote_host in default_hosts: + self.combobox.append_text(remote_host) + # Selezioniamo il primo host + self.combobox.set_active(0) + + self.pack_start(self.combobox) + self.combobox.show() + def get_remote_host(self): + return self.combobox.get_active_text() + class AuthBlock(gtk.HBox): - def __init__(self, default_spacing=5, left_padding=0, user = None): + def __init__(self, default_spacing=5, left_padding=0, user = None, + default_hosts = ['ssh.dm.unipi.it']): gtk.HBox.__init__(self) @@ -63,6 +80,17 @@ class AuthBlock(gtk.HBox): vbox1 = gtk.VBox() vbox2 = gtk.VBox() + label = LeftAlignedLabel("Server SSH", 20) + vbox1.pack_start (label) + label.show () + + if len(default_hosts) == 0: + raise IndexError('Not remote hosts specified. Aborting') + + self.remote_host = RemoteHostComboBox(default_hosts) + vbox2.pack_start(self.remote_host) + self.remote_host.show() + label = LeftAlignedLabel("Utente", 20) vbox1.pack_start( label ) label.show() @@ -89,6 +117,9 @@ class AuthBlock(gtk.HBox): def get_password(self): return self.password_field.get_text() + def get_remote_host(self): + return self.remote_host.get_remote_host() + class PrintButton(gtk.Button): def __init__(self, parent=None): @@ -107,6 +138,21 @@ class PrintButton(gtk.Button): else: raise RuntimeError('Invalid state %s' % state) +class QueueButton(gtk.Button): + + def __init__(self): + gtk.Button.__init__(self, "Visualizza coda") + + def set_state(self, state): + if state is "idle": + self.set_label("Visualizza coda") + else: + self.set_label("Recupero coda in corso...") + while gtk.events_pending(): + gtk.main_iteration (False) + + + class SelectFileWidget(gtk.HBox): @@ -149,17 +195,14 @@ file .ps da selezionare qui") class PrinterComboBox(gtk.HBox): - def __init__(self): + def __init__(self, printers = []): gtk.HBox.__init__(self) self.combobox = gtk.combo_box_new_text() - self.combobox.append_text("cdc7") - self.combobox.append_text("cdcpt") - self.combobox.append_text("cdc8") - self.combobox.append_text("cdc4") - self.combobox.append_text("cdc9") + for printer in printers: + self.combobox.append_text(printer) - self.combobox.set_active(1) + self.combobox.set_active(0) self.pack_start( self.combobox ) self.combobox.show() @@ -187,7 +230,7 @@ class PagePerPageComboBox(gtk.HBox): class PrinterSettingsBlock(gtk.HBox): - def __init__(self, default_spacing = 5, left_padding=0, filename = None): + def __init__(self, default_spacing = 5, left_padding=0, filename = None, printers = []): gtk.HBox.__init__(self) @@ -200,7 +243,7 @@ class PrinterSettingsBlock(gtk.HBox): vbox1.pack_start(label) label.show() - self.printer_chooser = PrinterComboBox() + self.printer_chooser = PrinterComboBox(printers = printers) vbox2.pack_start( self.printer_chooser ) self.printer_chooser.show() diff --git a/DrPrintGui/MainWin.py b/DrPrintGui/MainWin.py index b36173d..2c86991 100644 --- a/DrPrintGui/MainWin.py +++ b/DrPrintGui/MainWin.py @@ -11,8 +11,9 @@ import gtk, pygtk import os import sys -from Input import AuthBlock, PrinterSettingsBlock, PrintButton, LeftAlignedLabel, PageRangeBlock, OrientationSelect, SidesSelect -from Dialogs import ErrorDialog, MessageDialog, InfoDialog +from Input import AuthBlock, PrinterSettingsBlock, PrintButton, LeftAlignedLabel, \ + PageRangeBlock, OrientationSelect, SidesSelect, QueueButton +from Dialogs import ErrorDialog, MessageDialog, InfoDialog, QueueDialog from DrPrintBackend import PrintingError class MainWin(gtk.Window): @@ -75,11 +76,14 @@ class MainWin(gtk.Window): layout_box.pack_start(hbox, 20) + label = LeftAlignedLabel("Autenticazione (sui computer dell'Aula 4)") layout_box.pack_start( label ) label.show() - self.auth_block = AuthBlock(self.default_spacing, 10, user = self.user) + hosts = ['ssh.dm.unipi.it', 'ssh1.dm.unipi.it', 'ssh2.dm.unipi.it'] + self.auth_block = AuthBlock(self.default_spacing, 10, user = self.user, + default_hosts = hosts) layout_box.pack_start ( self.auth_block ) self.auth_block.show() @@ -88,8 +92,18 @@ class MainWin(gtk.Window): layout_box.pack_start(label) label.show() + # Piano terra e secondo piano + printers = ['cdcpt', 'cdcpp'] + + # Le stampanti numerate + printers.extend(map(lambda x : "cdc"+str(x), range(1,10))) + + # Togliamo la cdc2 che sembra non esistere + printers.remove("cdc2") + self.printer_settings_block = PrinterSettingsBlock(self.default_spacing, - filename = self.filename) + filename = self.filename, + printers = printers) layout_box.pack_start(self.printer_settings_block) self.printer_settings_block.show() @@ -113,9 +127,19 @@ class MainWin(gtk.Window): layout_box.pack_start(self.sides_select) self.sides_select.show() + # Bottoni finali, omogenei :) + hbox = gtk.HBox(True) + + self.queue_button = QueueButton() + hbox.pack_start(self.queue_button) + self.queue_button.show() + self.print_button = PrintButton() - layout_box.pack_start(self.print_button) + hbox.pack_start(self.print_button) self.print_button.show() + + layout_box.pack_start(hbox) + hbox.show () self.add (layout_box) @@ -123,8 +147,29 @@ class MainWin(gtk.Window): def connect_all(self): + self.queue_button.connect('clicked', self.queue_button_clicked_callback) self.print_button.connect('clicked', self.print_button_clicked_callback) + def queue_button_clicked_callback(self, widget): + self.queue_button.set_state("running") + printer = self.printer_settings_block.get_printer() + username = self.auth_block.get_username() + password = self.auth_block.get_password() + remote_host = self.auth_block.get_remote_host() + try: + jobs = self.backend.get_queue(printer, remote_host, username, password) + except RuntimeError, e: + dialog = ErrorDialog("Errore di connessione", + "Il seguente errore si รจ verificato durante il recupero della coda: %s" % e) + resp = dialog.run() + dialog.destroy() + self.queue_button.set_state("idle") + qd = QueueDialog(jobs, printer) + resp = qd.run() + qd.destroy() + + + def print_button_clicked_callback(self, widget): if not self.backend == None: @@ -140,6 +185,7 @@ class MainWin(gtk.Window): copies = self.printer_settings_block.get_copies() orientation = self.orientation_select.get_orientation() sides = self.sides_select.get_sides_select() + remote_host = self.auth_block.get_remote_host () resp = gtk.RESPONSE_OK @@ -167,7 +213,8 @@ Se vuoi continuare premi OK") page_range = page_range, copies = copies, orientation=orientation, - sides = sides) + sides = sides, + remote_host = remote_host) except PrintingError, e: # Comunichiamo il fallimento dialog = ErrorDialog("Errore di stampa", diff --git a/debian/changelog b/debian/changelog index 3395b39..db48f50 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +drprint (0.9-0-rc1) lucid; urgency=low + + * Prima implementazione della visualizzazione delle code di stampa + + -- Leonardo Robol Thu, 10 Jun 2010 17:49:08 +0200 + drprint (0.8-5) jaunty; urgency=low * Corrette dipendenze. -- 2.1.4