Viewing file: AdvancedServerSettings.py (12.6 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
#!/usr/bin/env python
## system-config-printer
## Copyright (C) 2008, 2009, 2010 Red Hat, Inc. ## Authors: ## Tim Waugh <twaugh@redhat.com>
## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 2 of the License, or ## (at your option) any later version.
## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details.
## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
from gettext import gettext as _ import cups import gobject import gtk import os import socket import tempfile import time
from errordialogs import *
class AdvancedServerSettings: RESOURCE="/admin/conf/cupsd.conf"
def __init__ (self, gui, on_apply=None): self.cupsconn = gui.cups self.on_apply = on_apply
# Signal handler IDs. self.handler_ids = {}
self.dialog = gui.ServerSettingsDialog browse_frame = gui.frameBrowseServers self.browse_treeview = gui.tvBrowseServers self.rbPreserveJobFiles = gui.rbPreserveJobFiles self.rbPreserveJobHistory = gui.rbPreserveJobHistory self.rbPreserveJobNone = gui.rbPreserveJobNone self.add = gui.btAdvServerAdd self.remove = gui.btAdvServerRemove
selection = self.browse_treeview.get_selection () selection.set_mode (gtk.SELECTION_MULTIPLE) self.connect (selection, 'changed', self.on_treeview_selection_changed)
for column in self.browse_treeview.get_columns(): self.browse_treeview.remove_column(column) col = gtk.TreeViewColumn ('', gtk.CellRendererText (), text=0) self.browse_treeview.append_column (col)
# Fetch cupsd.conf f = tempfile.TemporaryFile () try: self.cupsconn.getFile (self.RESOURCE, file=f) except cups.HTTPError, (s,): show_HTTP_Error (s, self.dialog) raise
def parse_yesno (line): arg1 = line.split (' ')[1].strip () if arg1 in ['true', 'on', 'enabled', 'yes']: return True if arg1 in ['false', 'off', 'disabled', 'no', '0']: return False try: if int (arg1) != 0: return True except: pass raise RuntimeError
preserve_job_history = True preserve_job_files = False browsing = True self.browse_poll = [] f.seek (0) for line in f.readlines (): l = line.lower ().strip () if l.startswith ("preservejobhistory "): try: preserve_job_history = parse_yesno (l) except: pass elif l.startswith ("preservejobfiles "): try: preserve_job_files = parse_yesno (l) except: pass elif l.startswith ("browsing "): try: browsing = parse_yesno (l) except: pass elif l.startswith ("browsepoll "): self.browse_poll.append (line[len ("browsepoll "):].strip ())
browse_frame.set_sensitive (browsing)
if preserve_job_files: self.rbPreserveJobFiles.set_active (True) elif preserve_job_history: self.rbPreserveJobHistory.set_active (True) else: self.rbPreserveJobNone.set_active (True)
self.preserve_job_history = preserve_job_history self.preserve_job_files = preserve_job_files
model = gtk.ListStore (gobject.TYPE_STRING) self.browse_treeview.set_model (model) for server in self.browse_poll: model.append (row=[server])
def connect (self, widget, signal, handler, reason=None): id = widget.connect (signal, handler) if not self.handler_ids.has_key (reason): self.handler_ids[reason] = [] self.handler_ids[reason].append ((widget, id))
def disconnect (self, reason=None): if self.handler_ids.has_key (reason): for (widget, id) in self.handler_ids[reason]: widget.disconnect (id) del self.handler_ids[reason]
def on_treeview_selection_changed (self, selection): self.remove.set_sensitive (selection.count_selected_rows () != 0)
def on_add_clicked (self, button): model = self.browse_treeview.get_model () iter = model.insert (0, row=[_("Enter IP address")]) button.set_sensitive (False) col = self.browse_treeview.get_columns ()[0] cell = col.get_cell_renderers ()[0] cell.set_property ('editable', True) self.browse_treeview.set_cursor ((0,), col, start_editing=True) self.connect (cell, 'edited', self.on_browse_poll_edited, 'edit') self.connect (cell, 'editing-canceled', self.on_browse_poll_edit_cancel, 'edit')
def on_browse_poll_edited (self, cell, path, newvalue): model = self.browse_treeview.get_model () iter = model.get_iter (path) model.set_value (iter, 0, newvalue) cell.stop_editing (canceled=False) cell.set_property ('editable', False) self.add.set_sensitive (True) self.disconnect ('edit')
valid = True # Check that it's a valid IP address or hostname. # First, is it an IP address? try: socket.getaddrinfo (newvalue, '0', socket.AF_UNSPEC, 0, 0, socket.AI_NUMERICHOST) except socket.gaierror: # No. Perhaps it's a hostname. labels = newvalue.split (".") seen_alpha = False for label in labels: if (label[0] == '-' or label.endswith ('-')): valid = False break for char in label: if not seen_alpha: if char.isalpha (): seen_alpha = True
if not (char.isalpha () or char.isdigit () or char == '-'): valid = False break
if not valid: break
if valid and not seen_alpha: valid = False
if valid: count = 0 i = model.get_iter_first () while i: if model.get_value (i, 0) == newvalue: count += 1 if count == 2: valid = False selection = self.browse_treeview.get_selection () selection.select_iter (i) break i = model.iter_next (i) else: model.remove (iter)
def on_browse_poll_edit_cancel (self, cell): cell.stop_editing (canceled=True) cell.set_property ('editable', False) model = self.browse_treeview.get_model () iter = model.get_iter ((0,)) model.remove (iter) self.add.set_sensitive (True) self.remove.set_sensitive (False) self.disconnect ('edit')
def on_remove_clicked (self, button): model = self.browse_treeview.get_model () selection = self.browse_treeview.get_selection () rows = selection.get_selected_rows () refs = map (lambda path: gtk.TreeRowReference (model, path), rows[1]) for ref in refs: path = ref.get_path () iter = model.get_iter (path) model.remove (iter)
def on_response (self, dialog, response): if (response == gtk.RESPONSE_CANCEL or response != gtk.RESPONSE_OK): self.disconnect () del self return
# See if there are changes. preserve_job_files = self.rbPreserveJobFiles.get_active () preserve_job_history = (preserve_job_files or self.rbPreserveJobHistory.get_active ()) model = self.browse_treeview.get_model () browse_poll = [] iter = model.get_iter_first () while iter: browse_poll.append (model.get_value (iter, 0)) iter = model.iter_next (iter)
if (set (browse_poll) == set (self.browse_poll) and preserve_job_files == self.preserve_job_files and preserve_job_history == self.preserve_job_history): self.disconnect () del self return
# Fetch cupsd.conf afresh f = tempfile.TemporaryFile () try: self.cupsconn.getFile (self.RESOURCE, file=f) except cups.HTTPError, (s,): show_HTTP_Error (s, dialog) return
job_history_line = job_files_line = browsepoll_lines = ""
# Default is to preserve job history if not preserve_job_history: job_history_line = "PreserveJobHistory No\n"
# Default is not to preserve job files. if preserve_job_files: job_files_line = "PreserveJobFiles Yes\n"
for server in browse_poll: browsepoll_lines += "BrowsePoll %s\n" % server
f.seek (0) conf = tempfile.TemporaryFile () wrote_preserve_history = wrote_preserve_files = False wrote_browsepoll = False has_browsepoll = False lines = f.readlines () for line in lines: l = line.lower ().strip () if l.startswith ("browsepoll "): has_browsepoll = True break
for line in lines: l = line.lower ().strip () if l.startswith ("preservejobhistory "): if wrote_preserve_history: # Don't write out another line with this keyword. continue # Alter this line before writing it out. line = job_history_line wrote_preserve_history = True elif l.startswith ("preservejobfiles "): if wrote_preserve_files: # Don't write out another line with this keyword. continue # Alter this line before writing it out. line = job_files_line wrote_preserve_files = True elif (has_browsepoll and l.startswith ("browsepoll ")): if wrote_browsepoll: # Ignore extra BrowsePoll lines. continue # Write new BrowsePoll section. conf.write (browsepoll_lines) wrote_browsepoll = True # Don't write out the original BrowsePoll line. continue elif (not has_browsepoll and l.startswith ("browsing ")): if not wrote_browsepoll: # Write original Browsing line. conf.write (line) # Write new BrowsePoll section. conf.write (browsepoll_lines) wrote_browsepoll = True continue
conf.write (line)
if not wrote_preserve_history: conf.write (job_history_line) if not wrote_preserve_files: conf.write (job_files_line) if not wrote_browsepoll: conf.write (browsepoll_lines)
conf.flush () fd = conf.fileno () os.lseek (fd, 0, os.SEEK_SET) try: self.cupsconn.putFile ("/admin/conf/cupsd.conf", fd=fd) except cups.HTTPError, (s,): show_HTTP_Error (s, dialog) return
# Give the server a chance to process our request. time.sleep (1)
# Now reconnect, in case the server needed to reload. try: attempt = 1 while attempt <= 5: try: self.cupsconn._connect () break except RuntimeError: # Connection failed. time.sleep (1) attempt += 1 except AttributeError: # _connect method is part of the authconn.Connection # interface, so don't fail if that method doesn't exist. pass
self.disconnect () self.on_apply () del self
|