|
Server : Apache/2.2.2 (Fedora) System : Linux App1.pathumtani.go.th 2.6.20-1.2320.fc5smp #1 SMP Tue Jun 12 19:40:16 EDT 2007 i686 User : apache ( 48) PHP Version : 5.2.9 Disable Function : NONE Directory : /usr/share/printconf/util/ |
Upload File : |
#!/usr/bin/python
## system-config-printer
## Sharing dialog implementation
## Copyright (C) 2001-2004 Red Hat, Inc.
## Copyright (C) 2002-2004 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.
import gettext
import gtk
import gtk.glade
import gnome
import gobject
import os
import signal
import string
import re
domain = 'printconf'
from rhpl.translate import _, N_
gtk.glade.bindtextdomain (domain, '/usr/share/locale')
import pyalchemist
def complain (window, msg, type = None):
"""Put up an error message dialog."""
if not type:
type = gtk.MESSAGE_ERROR
d = gtk.MessageDialog (window, 0, type, gtk.BUTTONS_OK, msg)
d.set_transient_for (window)
d.set_position (gtk.WIN_POS_CENTER_ON_PARENT)
d.run ()
d.destroy ()
class shareQueue:
"""The dialog implementation for sharing an existing queue."""
def __init__ (self, parent, xml):
self.parent = parent
# Widgets.
self.dialog = xml.get_widget ('sharingDialog')
self.shared_cb = xml.get_widget ('shared_cb')
self.allowed_hosts_view = xml.get_widget ('allowed_hosts_view')
self.hosts_dialog = xml.get_widget ('hostsDialog')
self.add_button = xml.get_widget ('sharing_add_button')
self.edit_button = xml.get_widget ('sharing_edit_button')
self.remove_button = xml.get_widget ('sharing_remove_button')
self.remove_button.set_sensitive (False)
self.all_hosts_rb = xml.get_widget ('all_hosts_rb')
self.netdev_rb = xml.get_widget ('netdev_rb')
self.netaddr_rb = xml.get_widget ('netaddr_rb')
self.ipaddr_rb = xml.get_widget ('ipaddr_rb')
self.netdev_vbox = xml.get_widget ('netdev_vbox')
self.netaddr_entry = xml.get_widget ('netaddr_entry')
self.netmask_entry = xml.get_widget ('netmask_entry')
self.ipaddr_entry = xml.get_widget ('ipaddr_entry')
self.sharing_notebook = xml.get_widget ('sharing_notebook')
self.browsing_cb = xml.get_widget ('browsing_cb')
self.lpd_cb = xml.get_widget ('lpd_cb')
# Set up allowed hosts TreeView
self.allowed_hosts_store = gtk.TreeStore (str, gobject.TYPE_PYOBJECT)
self.allowed_hosts_view.set_model (self.allowed_hosts_store)
col = gtk.TreeViewColumn ("", gtk.CellRendererText (), text = 0)
self.allowed_hosts_view.append_column (col)
# Prevent signals from causing unintended effects.
self.dialog_ready = 0
# Signals.
self.dialog.connect ('destroy', self.destroy)
xml.signal_connect ('on_shared_cb_toggled',
self.shared_checkbox_toggled)
xml.signal_connect ('on_allowed_hosts_view_cursor_changed',
self.cursor_changed)
xml.signal_connect ('on_sharing_add_button_clicked',
self.add_clicked)
xml.signal_connect ('on_sharing_edit_button_clicked',
self.edit_clicked)
xml.signal_connect ('on_allowed_hosts_view_row_activated',
self.row_activated)
xml.signal_connect ('on_sharing_remove_button_clicked',
self.remove_clicked)
xml.signal_connect ('on_lpd_cb_toggled',
self.lpd_checkbox_toggled)
xml.signal_connect ('on_all_hosts_rb_toggled',
self.all_hosts_radiobutton_toggled)
xml.signal_connect ('on_netdev_rb_toggled',
self.netdev_radiobutton_toggled)
xml.signal_connect ('on_netaddr_rb_toggled',
self.netaddr_radiobutton_toggled)
xml.signal_connect ('on_netaddr_entry_focus_out_event',
self.netaddr_entry_focus_out_event)
xml.signal_connect ('on_ipaddr_rb_toggled',
self.ipaddr_radiobutton_toggled)
self.ipaddr_re_str = "([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)"
self.netdev_re = re.compile ("^[a-z]+[0-9]+$")
self.netdevs_re = re.compile ("^([a-z]+[0-9]+,)+$")
# -------------------------------
# Handle the window being deleted
# -------------------------------
def destroy (self, dialog):
"""Callback for the window being deleted."""
dialog.hide ()
#--------------------------
# Sharing properties dialog
#--------------------------
def shareQueueDialog (self, iter = None):
"""
Run a dialog for sharing the queue.
iter: Iter from queue tree.
"""
self.dialog_ready = 0
self.lpd_warning_issued = 0
self.queue_tree_iter = iter
self.sharing_globals = self.get_sharing_globals (self)
if iter:
self.name = self.parent.queue_store.get_value (iter, 1)
self.dialog.set_title (_("Sharing properties - %s") % self.name)
self.sharing_notebook.set_show_tabs (True)
self.sharing_notebook.set_current_page (0)
# Prepare the widgets
self.add_button.set_sensitive (True)
for button in [self.edit_button, self.remove_button]:
button.set_sensitive (False)
store = self.allowed_hosts_store
store.clear ()
self.all_hosts_set = 0
try:
del self.sharing
except:
pass
try:
devs = ""
queue = self.parent.name_dict[self.name]["queue"]
self.sharing = queue["sharing"]
self.shared_cb.set_active (False)
for allowed in self.sharing:
if self.netdev_re.match (allowed.value):
devs += allowed.value + ","
continue
iter = store.append (None)
store.set_value (iter, 1, allowed.value)
store.set_value (iter, 0,
self.describe_hosts (allowed.value))
self.shared_cb.set_active (True)
if allowed.value == "ALL":
self.all_hosts_set = 1
if devs:
iter = store.append (None)
store.set_value (iter, 1, devs)
store.set_value (iter, 0, self.describe_hosts (devs))
self.shared_cb.set_active (True)
except:
# Reset the widgets
self.shared_cb.set_active (False)
self.shared_checkbox_toggled (self.shared_cb)
else:
self.dialog.set_title (_("Sharing properties"))
self.sharing_notebook.set_show_tabs (False)
self.sharing_notebook.set_current_page (1)
browsing = True
try:
if not self.sharing_globals["browsing"].value:
browsing = False
except:
pass
self.browsing_cb.set_active (browsing)
self.init_lpd_checkbutton ()
# Run the dialog.
self.dialog.set_transient_for (self.parent.toplevel)
self.dialog.set_position (gtk.WIN_POS_NONE)
self.dialog_ready = 1
backup_ctx = self.parent.conf.queue_edit.dynamic_queue_ctx.copy ()
while 1:
response = self.dialog.run ()
# Deal with the consequences.
if response == gtk.RESPONSE_OK:
if self.validate_and_pull ():
continue
break
elif (response == gtk.RESPONSE_CANCEL or
response == gtk.RESPONSE_DELETE_EVENT):
self.parent.conf.dynamic_queue_ctx = backup_ctx
break
elif response == gtk.RESPONSE_HELP:
html = 'printconf-share.html'
gnome.url_show ("file://%s/%s" %
(self.parent.conf.conf.printconf_help_dir,
html))
# Deal with non-ADL options.
try:
if self.lpd_active != self.lpd_cb.get_active ():
if self.lpd_cb.get_active ():
state = "on"
else:
state = "off"
os.system ("/sbin/chkconfig cups-lpd %s" % state)
os.system ("/sbin/service xinetd reload")
except:
pass
self.destroy (self.dialog)
return response == gtk.RESPONSE_OK
def validate_and_pull (self):
"""Returns non-zero if there is a problem."""
if self.queue_tree_iter:
if not self.shared_cb.get_active ():
try:
self.sharing.unlink ()
except:
pass
return 0
try:
self.sharing.unlink ()
except:
pass
queue = self.parent.name_dict[self.name]["queue"]
self.sharing = queue.addData (pyalchemist.AdmListType, "sharing")
self.sharing.anonymous = 1
i = 1
store = self.allowed_hosts_store
for row in store:
def add_hosts_config (name, value):
self.sharing.addData (pyalchemist.AdmStringType,
name).value = value
iter = store.get_iter (row.path)
string = store.get_value (iter, 1)
if self.netdevs_re.match (string):
for each in string.split (","):
if each:
add_hosts_config ("hosts" + str (i), each)
i += 1
else:
add_hosts_config ("hosts" + str (i), string)
i += 1
if not self.sharing_globals:
self.sharing_globals = self.get_sharing_globals (create = 1)
try:
self.sharing_globals["browsing"].unlink ()
except:
pass
browsing = self.browsing_cb.get_active ()
self.sharing_globals.addData (pyalchemist.AdmBoolType,
"browsing").value = browsing
return 0
def validate_dotted_quad (self, list):
"""Return non-zero if there is a problem."""
valid = 1
for octet in list:
v = int (octet)
if v < 0 or v > 255:
valid = 0
break
return not valid
def describe_hosts (self, string):
"""User-presentable description of ADL hosts string."""
if string == "ALL":
return _("All hosts")
if self.netdevs_re.match (string):
devs = ""
count = 0
for dev in string.split (","):
if dev:
if devs:
devs += ", "
devs += dev
count += 1
if count == 1:
return _("Network device %s") % devs
return _("Network devices %s") % devs
netaddr_re = re.compile ("^%s/%s$" % (self.ipaddr_re_str,
self.ipaddr_re_str))
match = netaddr_re.match (string)
if match and not self.validate_dotted_quad (match.groups ()):
return _("Network address %s") % string
ipaddr_re = re.compile ("^%s$" % self.ipaddr_re_str)
match = ipaddr_re.match (string)
if match and not self.validate_dotted_quad (match.groups ()):
return string
return _("(unknown)")
def set_button_sensitivity (self):
edit_remove = False
store, iter = self.allowed_hosts_view.get_selection ().get_selected ()
if iter:
edit_remove = True
self.add_button.set_sensitive (not self.all_hosts_set)
for button in [self.edit_button, self.remove_button]:
button.set_sensitive (edit_remove)
def get_sharing_globals (self, create = 0):
qe = self.parent.conf.queue_edit
try:
return qe.dynamic_queue_ctx.data['/printconf/sharing_globals']
except:
pass
try:
return qe.static_queue_ctx.data['/printconf/sharing_globals']
except:
pass
if create:
toplevel = qe.dynamic_queue_ctx.data['/printconf']
return toplevel.addData (pyalchemist.AdmListType,
"sharing_globals")
return None
def init_lpd_checkbutton (self):
cb = self.lpd_cb
signal.signal (signal.SIGCHLD, signal.SIG_DFL)
f = os.popen ('LC_ALL=C /sbin/chkconfig --list cups-lpd 2>/dev/null')
ls = f.readlines ()
try:
state = ls[0].split ('\t')[1].strip ()
self.lpd_active = state == "on"
cb.set_active (self.lpd_active)
cb.set_sensitive (True)
except:
cb.set_active (False)
cb.set_sensitive (False)
#---------------------------------------
# Handlers for sharing properties dialog
#---------------------------------------
def shared_checkbox_toggled (self, checkbox):
active = checkbox.get_active ()
self.allowed_hosts_view.set_sensitive (active)
if active and len (self.allowed_hosts_store) == 0:
store = self.allowed_hosts_store
iter = store.append (None)
all = "ALL"
store.set_value (iter, 1, all)
store.set_value (iter, 0, self.describe_hosts (all))
self.all_hosts_set = 1
sel = self.allowed_hosts_view.get_selection ()
sel.select_iter (iter)
self.set_button_sensitivity ()
else:
if active:
self.set_button_sensitivity ()
else:
for button in [self.add_button, self.edit_button,
self.remove_button]:
button.set_sensitive (False)
def add_clicked (self, button):
self.run_hosts_dialog (_("Add allowed hosts - %s") % self.name)
def edit_clicked (self, button = None):
store, iter = self.allowed_hosts_view.get_selection ().get_selected ()
self.run_hosts_dialog (_("Edit allowed hosts - %s") % self.name, iter)
def remove_clicked (self, button):
store, iter = self.allowed_hosts_view.get_selection ().get_selected ()
string = store.get_value (iter, 1)
store.remove (iter)
if string == "ALL":
self.all_hosts_set = False
self.set_button_sensitivity ()
def cursor_changed (self, view):
self.set_button_sensitivity ()
def row_activated (self, view):
self.edit_clicked ()
def lpd_checkbox_toggled (self, checkbox):
if self.lpd_warning_issued:
return
if not checkbox.get_active ():
return
if not self.dialog_ready:
return
self.lpd_warning_issued = 1
complain (self.dialog,
_("LPD connections will be accepted\n"
"on all interfaces, and jobs for\n"
"all queues will be accepted."),
gtk.MESSAGE_WARNING)
#---------------------
# Allowed hosts dialog
#---------------------
def run_hosts_dialog (self, title, iter = None):
"""
Run a dialog for adding/editing allowed hosts.
title: Title to give the dialog.
"""
self.hosts_dialog.set_title (title)
# Reset the widgets.
for child in self.netdev_vbox.get_children ():
self.netdev_vbox.remove (child)
for line in file ("/proc/net/dev").readlines ():
if line.find ("|") != -1:
continue
end = line.find (":")
if end == -1:
continue
dev = line[:end].strip ()
if dev == "lo":
continue
cb = gtk.CheckButton (dev)
self.netdev_vbox.add (cb)
self.netdev_vbox.show_all ()
self.netaddr_entry.set_text ('')
self.netmask_entry.set_text ('')
self.ipaddr_entry.set_text ('')
self.all_hosts_rb.set_active (True)
self.all_hosts_radiobutton_toggled (self.all_hosts_rb)
if iter:
string = self.allowed_hosts_store.get_value (iter, 1)
if self.netdevs_re.match (string):
self.netdev_rb.set_active (True)
self.netdev_radiobutton_toggled (self.netdev_rb)
done = 0
for dev in self.netdev_vbox.get_children ():
for each in string.split (","):
if each:
if dev.get_label () == each:
dev.set_active (True)
done = 1
if not done:
for each in string.split (","):
if each:
dev = gtk.CheckButton (each)
self.netdev_vbox.add (dev)
dev.set_active (True)
else:
netaddr_re = re.compile ("^%s/%s$" % (self.ipaddr_re_str,
self.ipaddr_re_str))
match = netaddr_re.match (string)
if match:
self.netaddr_rb.set_active (True)
self.netaddr_radiobutton_toggled (self.netaddr_rb)
quad = match.groups ()
self.netaddr_entry.set_text ("%s.%s.%s.%s" % quad[:4])
self.netmask_entry.set_text ("%s.%s.%s.%s" % quad[4:])
else:
ipaddr_re = re.compile ("^%s$" % self.ipaddr_re_str)
if ipaddr_re.match (string):
self.ipaddr_rb.set_active (True)
self.ipaddr_radiobutton_toggled (self.ipaddr_rb)
self.ipaddr_entry.set_text (string)
# Run the dialog.
self.hosts_dialog.set_transient_for (self.dialog)
self.hosts_dialog.set_position (gtk.WIN_POS_CENTER_ON_PARENT)
while 1:
response = self.hosts_dialog.run ()
# Deal with the consequences.
if response == gtk.RESPONSE_OK:
if self.validate_hosts_and_pull ():
continue
if iter and not self.all_hosts_set:
self.allowed_hosts_store.remove (iter)
break
elif (response == gtk.RESPONSE_CANCEL or
response == gtk.RESPONSE_DELETE_EVENT):
break
elif response == gtk.RESPONSE_HELP:
gnome.url_show ("file://%s/printconf-share.html#FIG-PRINTING-SHARE-HOSTS" %
self.parent.conf.conf.printconf_help_dir)
self.destroy (self.hosts_dialog)
# Merge network devices.
store = self.allowed_hosts_store
netdevs_iter = None
devs = []
for row in store:
iter = store.get_iter (row.path)
string = store.get_value (iter, 1)
if self.netdevs_re.match (string):
if netdevs_iter:
for dev in string.split (","):
if dev:
try:
devs.index (dev)
except:
devs.append (dev)
store.remove (iter)
else:
netdevs_iter = iter
devs = string.split (",")
del devs[len (devs) - 1]
if netdevs_iter:
devstr = ""
for dev in devs:
devstr += dev + ","
store.set_value (netdevs_iter, 1, devstr)
store.set_value (netdevs_iter, 0, self.describe_hosts (devstr))
self.allowed_hosts_view.get_selection ().select_iter (netdevs_iter)
self.set_button_sensitivity ()
def get_hosts_string (self):
"""Form the ADL string representing the allowed hosts."""
if self.all_hosts_rb.get_active ():
return "ALL"
if self.netdev_rb.get_active ():
string = ""
for dev in self.netdev_vbox.get_children ():
if dev.get_active ():
string += dev.get_label () + ","
return string
if self.netaddr_rb.get_active ():
addr = self.netaddr_entry.get_text ()
mask = self.netmask_entry.get_text ()
ipaddr_re = re.compile ("^%s$" % self.ipaddr_re_str)
match = ipaddr_re.match (addr)
if not match or self.validate_dotted_quad (match.groups ()):
complain (self.hosts_dialog, _("Invalid network address"))
self.netaddr_entry.grab_focus ()
return None
match = ipaddr_re.match (mask)
if not match:
try:
cidr = int (mask)
if cidr <= 32:
def n_high_bits (n):
q = 0
for b in range (1, 9):
if n < b:
break
q += pow (2, 8 - b)
return q
quad = [0, 0, 0, 0]
for i in range (4):
if cidr >= 8:
quad[i] = 255
else:
quad[i] = n_high_bits (cidr)
cidr -= 8
if cidr < 0:
break
mask = "%d.%d.%d.%d" % tuple (quad)
self.netmask_entry.set_text (mask)
match = ipaddr_re.match (mask)
except:
pass
if not match or self.validate_dotted_quad (match.groups ()):
complain (self.hosts_dialog, _("Invalid netmask"))
self.netmask_entry.grab_focus ()
return None
return "%s/%s" % (addr, mask)
if self.ipaddr_rb.get_active ():
ipaddr = self.ipaddr_entry.get_text ()
ipaddr_re = re.compile ("^%s$" % self.ipaddr_re_str)
match = ipaddr_re.match (ipaddr)
if not match or self.validate_dotted_quad (match.groups ()):
complain (self.hosts_dialog, _("Invalid IP address"))
self.ipaddr_entry.grab_focus ()
return None
return ipaddr
return None
def validate_hosts_and_pull (self):
"""Returns non-zero if there was a problem."""
string = self.get_hosts_string ()
if not string:
return 1
store = self.allowed_hosts_store
if string == "ALL":
self.all_hosts_set = 1
store.clear ()
else:
self.all_hosts_set = 0
iter = store.append (None)
store.set_value (iter, 1, string)
store.set_value (iter, 0, self.describe_hosts (string))
self.allowed_hosts_view.get_selection ().select_iter (iter)
return 0
#----------------------------------
# Handlers for allowed hosts dialog
#----------------------------------
def all_hosts_radiobutton_toggled (self, rb):
for each in [self.netaddr_entry,
self.netmask_entry,
self.ipaddr_entry]:
each.set_sensitive (False)
for each in self.netdev_vbox.get_children ():
each.set_sensitive (False)
def netdev_radiobutton_toggled (self, rb):
for each in [self.netaddr_entry,
self.netmask_entry,
self.ipaddr_entry]:
each.set_sensitive (False)
for each in self.netdev_vbox.get_children ():
each.set_sensitive (True)
def netaddr_radiobutton_toggled (self, rb):
self.netaddr_entry.set_sensitive (True)
self.netmask_entry.set_sensitive (True)
self.ipaddr_entry.set_sensitive (False)
for each in self.netdev_vbox.get_children ():
each.set_sensitive (False)
self.netaddr_entry.grab_focus ()
def netaddr_entry_focus_out_event (self, *args):
entry = self.netmask_entry
if entry.get_text () == '':
netaddr = self.netaddr_entry.get_text ()
ipaddr_re = re.compile ("^%s$" % self.ipaddr_re_str)
match = ipaddr_re.match (netaddr)
if match:
first = match.groups ()[0]
if first < 128:
netmask = "255.0.0.0"
elif first < 192:
netmask = "255.255.0.0"
else:
netmask = "255.255.255.0"
entry.set_text (netmask)
def ipaddr_radiobutton_toggled (self, rb):
self.netaddr_entry.set_sensitive (False)
self.netmask_entry.set_sensitive (False)
self.ipaddr_entry.set_sensitive (True)
for each in self.netdev_vbox.get_children ():
each.set_sensitive (False)
self.ipaddr_entry.grab_focus ()
# Local Variables:
# py-indent-offset: 4
# End: