2 Created on May 17, 2010
4 @author: Sergio Martins
8 pygtk.require20() #require pygtk version 2.0
14 #sys.path.append('/usr/local/samba/lib/python2.7/site-packages/')
15 # for use against the default binaries from default .configure.developer for use on python 2.7
16 # Uncomment the above line if it is yor your config , else edit it as required
25 from sambagtk.dialogs import AboutDialog
26 from sambagtk.sam import SAMConnectDialog
27 from sambagtk.pysrvsvc import srvsvcConnectDialog
30 class SambaUtilities(object):
32 def __init__(self, connection_args={}, additional_connection_arguments={}):
36 # these are the old windows of the utilities. We reparent the main
37 # widget so these arn't displayed but we need the handle so we can
38 # call functions and grab objects
39 self.sam_window = None
40 self.regedit_window = None
41 self.svcctl_window = None
42 self.crontab_window = None
43 self.srvsvc_window = None
44 self.srvsvc_init= False
46 self.connection_args = connection_args
47 self.additional_connection_args = {} #arguments not supported by all utilities, such as domain_index
48 self.additional_connection_args.update({"info_callback":self.server_info_callback}) #to save info or get updated info
49 self.print_redirect_sring = ""
51 self.update_sensitivity()
53 self.push_status_message("Utility started successfully.")
54 self.utilites_notebook.grab_focus() #So switching to the regedit tab doesn't automatically focus the keys tree view
56 if (connection_args.has_key("connect_now") and connection_args["connect_now"]):
57 self.on_connect_all_button_clicked(None)
61 # get a builder and put it to work
62 builder = gtk.Builder()
63 builder.add_from_file("main.glade")
65 # dictionary for connections
66 connections = {"on_main_window_destroy": gtk.main_quit,
67 "on_main_window_key_press_event": self.on_main_window_key_press_event,
69 "on_connect_all_item_activate": self.on_connect_all_button_clicked,
70 "on_disconnect_all_item_activate": self.on_disconnect_all_button_clicked,
71 "on_quit_item_activate": self.on_quit_item_activate,
72 "on_clear_log_activate": self.on_clear_log_activate,
73 "on_connection_info_item_activate": self.on_connection_info_item_activate,
74 "on_about_item_activate": self.on_about_item_activate,
76 "on_connect_all_button_clicked": self.on_connect_all_button_clicked,
77 "on_disconnect_all_button_clicked": self.on_disconnect_all_button_clicked,
78 "on_clear_log_button_clicked": self.on_clear_log_activate,
80 "on_utility_notebook_switch_page": self.on_utility_notebook_switch_page,
84 builder.connect_signals(connections)
87 self.window = builder.get_object("main_window")
88 self.menubar_viewport = builder.get_object("menubar_viewport")
89 self.menubar = builder.get_object("menubar")
90 self.connect_all_item = builder.get_object("connect_all_item")
91 self.disconnect_all_item = builder.get_object("disconnect_all_item")
93 self.toolbar_viewport = builder.get_object("toolbar_viewport")
94 self.toolbar = builder.get_object("toolbar")
95 self.connect_all_button = builder.get_object("connect_all_button")
96 self.disconnect_all_button = builder.get_object("disconnect_all_button")
98 self.utilites_notebook = builder.get_object("utility_notebook")
100 self.server_label = builder.get_object("server_label")
101 self.username_label = builder.get_object("username_label")
102 self.status_label = builder.get_object("status_label")
103 self.messages_textview = builder.get_object("messages_textview")
105 self.sam_viewport = builder.get_object("sam_viewport")
106 self.svcctl_viewport = builder.get_object("svcctl_viewport")
107 self.crontab_viewport = builder.get_object("crontab_viewport")
108 self.regedit_viewport = builder.get_object("regedit_viewport")
109 self.srvsvc_viewport = builder.get_object("srvsvc_viewport")
111 self.progressbar = builder.get_object("progressbar")
112 self.statusbar = builder.get_object("statusbar")
115 def init_sam_page(self):
117 args = self.connection_args.copy()
118 if self.additional_connection_args.has_key("domain_index"):
119 args.update({"domain_index":self.additional_connection_args["domain_index"]})
120 if self.additional_connection_args.has_key("info_callback"):
121 args.update({"info_callback":self.additional_connection_args["info_callback"]})
123 self.sam_window = pygwsam.SAMWindow(**args) #start up the utility
124 self.sam_window.users_groups_notebook.reparent(self.sam_viewport) #reparent the main widget into a notebook tab
125 self.sam_viewport.show_all() #unhide all widgets
127 #We'll be displaying this later. We need to unparent it before attaching it to another container
128 self.sam_window.menubar.unparent()
129 self.sam_window.toolbar.unparent()
130 self.sam_window.statusbar = self.statusbar #we simply tell the utility to use our status bar instead
132 self.set_status("User tab initialized.")
133 self.update_sensitivity()
135 def init_srvsvc_page(self):
137 args = self.connection_args.copy()
138 if self.additional_connection_args.has_key("info_callback"):
139 args.update({"info_callback":self.additional_connection_args["info_callback"]})
141 self.srvsvc_window = pygwshare.ShareWindow(**args) #start up the utility
142 self.srvsvc_window.share_notebook.reparent(self.srvsvc_viewport) #reparent the main widget into a notebook tab
143 self.srvsvc_viewport.show_all() #unhide all widgets
145 #We'll be displaying this later. We need to unparent it before attaching it to another container
147 self.srvsvc_window.toolbar.unparent()
148 self.srvsvc_window.statusbar = self.statusbar #we simply tell the utility to use our status bar instead
150 self.set_status("Share Manager tab initialized.")
151 self.update_sensitivity()
153 def init_regedit_page(self):
154 args = self.connection_args.copy()
155 if self.additional_connection_args.has_key("info_callback"):
156 args.update({"info_callback":self.additional_connection_args["info_callback"]})
157 self.regedit_window = pygwregedit.RegEditWindow(**args) #start up the utility
158 self.regedit_window.hpaned.reparent(self.regedit_viewport) #reparent the main widget into a notebook tab
159 self.regedit_viewport.show_all() #unhide all widgets
161 self.regedit_window.menubar.unparent()
162 self.regedit_window.toolbar.unparent()
163 self.regedit_window.progressbar = self.progressbar
164 self.regedit_window.statusbar = self.statusbar
166 self.set_status("Regedit tab initialized.")
167 self.update_sensitivity()
169 def init_svcctl_page(self):
170 args = self.connection_args.copy()
171 if self.additional_connection_args.has_key("info_callback"):
172 args.update({"info_callback":self.additional_connection_args["info_callback"]})
173 self.svcctl_window = pygwsvcctl.SvcCtlWindow(**args) #start up the utility
174 self.svcctl_window.scrolledwindow.reparent(self.svcctl_viewport) #reparent the main widget into a notebook tab
175 self.svcctl_viewport.show_all() #unhide all widgets
177 self.svcctl_window.menubar.unparent()
178 self.svcctl_window.toolbar.unparent()
179 self.svcctl_window.progressbar = self.progressbar
180 self.svcctl_window.statusbar = self.statusbar
182 self.set_status("Services tab initialized.")
183 self.update_sensitivity()
185 def init_crontab_page(self):
186 args = self.connection_args.copy()
187 if self.additional_connection_args.has_key("info_callback"):
188 args.update({"info_callback":self.additional_connection_args["info_callback"]})
189 self.crontab_window = pygwcrontab.CronTabWindow(**args) #start up the utility
190 self.crontab_window.scrolledwindow.reparent(self.crontab_viewport) #reparent the main widget into a notebook tab
191 self.crontab_viewport.show_all() #unhide all widgets
193 self.crontab_window.menubar.unparent()
194 self.crontab_window.toolbar.unparent()
195 self.crontab_window.statusbar = self.statusbar
197 self.set_status("Scheduled tasks tab initialized.")
198 self.update_sensitivity()
200 def sam_initialized(self):
201 return self.sam_window is not None
203 def regedit_initialized(self):
204 return self.regedit_window is not None
206 def srvsvc_initialized (self):
207 return self.srvsvc_window is not None
209 def svcctl_initialized(self):
210 return self.svcctl_window is not None
212 def crontab_initialized(self):
213 return self.crontab_window is not None
215 def update_sensitivity(self):
216 sam_connected = self.sam_initialized() and self.sam_window.connected()
217 srvsvc_connected = self.srvsvc_initialized() and self.srvsvc_window.connected()
218 regedit_connected = self.regedit_initialized() and self.regedit_window.connected()
219 svcctl_connected = self.svcctl_initialized() and self.svcctl_window.connected()
220 crontab_connected = self.crontab_initialized() and self.crontab_window.connected()
221 all_connected = sam_connected and regedit_connected and svcctl_connected and crontab_connected and srvsvc_connected
222 all_disconnected = (not sam_connected) and (not regedit_connected) and (not svcctl_connected) and (not crontab_connected) and (not srvsvc_connected)
224 self.connect_all_button.set_sensitive(not all_connected)
225 self.disconnect_all_button.set_sensitive(not all_disconnected)
226 self.connect_all_item.set_sensitive(not all_connected)
227 self.disconnect_all_item.set_sensitive(not all_disconnected)
229 self.server_label.set_text(self.connection_args.has_key("server") and self.connection_args["server"] or "Unknown")
230 self.username_label.set_text(self.connection_args.has_key("username") and self.connection_args["username"] or "Unknwon")
232 self.status_label.set_text("All connected")
233 elif (all_disconnected):
234 self.status_label.set_text("All disconnected")
236 connected_utilities = []
238 connected_utilities.append("User Manager")
240 connected_utilities.append("Share Manager")
241 if regedit_connected:
242 connected_utilities.append("Registry Editor")
244 connected_utilities.append("Services Manager")
245 if crontab_connected:
246 connected_utilities.append("Task Scheduler")
247 if len(connected_utilities) > 1:
248 connected_utilities[-1] = "and %s" % connected_utilities[-1]
249 self.status_label.set_text("%s %s" % (", ".join(connected_utilities), "connected."))
251 def server_info_callback(self, server = "", username = "", transport_type = None):
253 self.connection_args.update({"server":server})
255 self.connection_args.update({"username":username})
257 self.connection_args.update({"transport_type":transport_type})
259 def run_message_dialog(self, type, buttons, message, parent = None):
263 message_box = gtk.MessageDialog(parent, gtk.DIALOG_MODAL, type, buttons, message)
264 response = message_box.run()
269 def run_connect_all_dialog(self):
270 """Runs the connection dialog and saves connection arguments to self.connection_args
272 returns True if arguments were uptained successfully"""
273 #TODO in this function: handle domain selection
275 #args and their default values
276 important_args = {"server":"", "username":"", "transport_type":0, }
277 for item in important_args.keys():
278 args.update(self.connection_args.has_key(item) and {item:self.connection_args[item]} or {item:important_args[item]})
280 dialog = SAMConnectDialog(**args)
283 # loop to handle the failures
285 response_id = dialog.run()
287 if (response_id != gtk.RESPONSE_OK):
291 server = dialog.get_server_address()
292 username = dialog.get_username()
293 if server != "" and username != "":
294 self.connection_args.update({"server":server})
295 self.connection_args.update({"username":username})
296 self.connection_args.update({"transport_type":dialog.get_transport_type()})
297 self.connection_args.update({"password":dialog.get_password()})
298 self.connection_args.update({"connect_now":True})
299 self.additional_connection_args.update({"domain_index":0}) #TODO: get domain index
302 self.run_message_dialog(gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, "You must enter a server address and username.")
308 def write(self, string): #Make this class a writeable object. Used so we can redirect print statements
310 self.push_status_message(self.print_redirect_sring)
311 print >>sys.__stdout__, self.print_redirect_sring #also print the string normally
312 self.print_redirect_sring = ""
314 self.print_redirect_sring += string
316 def push_status_message(self, message):
317 """Pushes a message to the status textview in the main tab. This function inserts a \"\\n\" for you."""
318 buffer = self.messages_textview.get_buffer()
319 text = buffer.get_text(buffer.get_start_iter(), buffer.get_end_iter())
320 text += message + "\n"
321 buffer.set_text(text)
323 #scroll to the bottom
324 self.messages_textview.scroll_to_iter(buffer.get_end_iter(), 0.0)
326 def set_status(self, message):
327 self.statusbar.pop(0)
328 self.statusbar.push(0, message)
329 self.push_status_message(message)
331 def on_main_window_key_press_event(self, widget, event):
332 current_page = self.utilites_notebook.get_current_page()
334 if current_page == 1:
335 self.sam_window.on_key_press(widget, event)
336 elif current_page == 2:
337 self.srvsvc_window.on_key_press(widget, event)
338 elif current_page == 3:
339 self.regedit_window.on_key_press(widget, event)
340 elif current_page == 4:
341 self.svcctl_window.on_key_press(widget, event)
342 elif current_page == 5:
343 self.crontab_window.on_key_press(widget, event)
345 def on_utility_notebook_switch_page(self, widget, page, page_num):
346 if page_num == 0: #main page
349 children = self.menubar_viewport.get_children()
350 self.menubar_viewport.remove(children[0])
351 self.menubar_viewport.add(self.menubar)
352 self.menubar_viewport.show_all()
354 children = self.toolbar_viewport.get_children()
355 self.toolbar_viewport.remove(children[0])
356 self.toolbar_viewport.add(self.toolbar)
357 self.toolbar_viewport.show_all()
359 self.update_sensitivity()
361 elif page_num == 1: #Sam page
362 if self.sam_viewport.child == None:
366 children = self.menubar_viewport.get_children()
367 self.menubar_viewport.remove(children[0])
368 self.menubar_viewport.add(self.sam_window.menubar)
369 self.menubar_viewport.show_all()
372 children = self.toolbar_viewport.get_children()
373 self.toolbar_viewport.remove(children[0])
374 self.toolbar_viewport.add(self.sam_window.toolbar)
375 self.toolbar_viewport.show_all()
378 elif page_num == 2: #Share page
379 if self.srvsvc_viewport.child == None:
380 self.init_srvsvc_page()
383 children = self.menubar_viewport.get_children()
384 self.menubar_viewport.remove(children[0])
385 if self.srvsvc_init is False:
386 self.srvsvc_window.menubar.reparent(self.menubar_viewport)
387 self.srvsvc_init = True
389 self.menubar_viewport.add(self.srvsvc_window.menubar)
390 self.menubar_viewport.show_all()
393 children = self.toolbar_viewport.get_children()
394 self.toolbar_viewport.remove(children[0])
395 self.srvsvc_window.toolbar.unparent()
396 self.toolbar_viewport.add(self.srvsvc_window.toolbar)
397 self.toolbar_viewport.show_all()
399 self.srvsvc_window.hide()
401 elif page_num == 3: #Regedit page
402 if self.regedit_viewport.child == None:
403 self.init_regedit_page()
406 children = self.menubar_viewport.get_children()
407 self.menubar_viewport.remove(children[0])
408 self.menubar_viewport.add(self.regedit_window.menubar)
409 self.menubar_viewport.show_all()
412 children = self.toolbar_viewport.get_children()
413 self.toolbar_viewport.remove(children[0])
414 self.toolbar_viewport.add(self.regedit_window.toolbar)
415 self.toolbar_viewport.show_all()
417 elif page_num == 4: #Services page
418 if self.svcctl_viewport.child == None:
419 self.init_svcctl_page()
422 children = self.menubar_viewport.get_children()
423 self.menubar_viewport.remove(children[0])
424 self.menubar_viewport.add(self.svcctl_window.menubar)
425 self.menubar_viewport.show_all()
428 children = self.toolbar_viewport.get_children()
429 self.toolbar_viewport.remove(children[0])
430 self.toolbar_viewport.add(self.svcctl_window.toolbar)
431 self.toolbar_viewport.show_all()
433 elif page_num == 5: #Crontab page
434 if self.crontab_viewport.child == None:
435 self.init_crontab_page()
438 children = self.menubar_viewport.get_children()
439 self.menubar_viewport.remove(children[0])
440 self.menubar_viewport.add(self.crontab_window.menubar)
441 self.menubar_viewport.show_all()
444 children = self.toolbar_viewport.get_children()
445 self.toolbar_viewport.remove(children[0])
446 self.toolbar_viewport.add(self.crontab_window.toolbar)
447 self.toolbar_viewport.show_all()
449 def on_connect_all_button_clicked(self, widget):
451 if self.connection_args.has_key("connect_now") and self.connection_args["connect_now"]:
452 #if the user specified --connect-now then we probably have enough arguments to connect
454 if self.sam_initialized():
455 if not self.sam_window.connected():
456 self.sam_window.on_connect_item_activate(None, **self.connection_args)
460 if self.srvsvc_initialized():
461 if not self.srvsvc_window.connected():
462 self.srvsvc_window.on_connect_item_activate(None, **self.connection_args)
464 self.init_srvsvc_page()
466 if self.regedit_initialized():
467 if not self.regedit_window.connected():
468 self.regedit_window.on_connect_item_activate(None, **self.connection_args)
470 self.init_regedit_page()
472 if self.svcctl_initialized():
473 if not self.svcctl_window.connected():
474 self.svcctl_window.on_connect_item_activate(None, **self.connection_args)
476 self.init_svcctl_page()
478 if self.crontab_initialized():
479 if not self.crontab_window.connected():
480 self.crontab_window.on_connect_item_activate(None, **self.connection_args)
482 self.init_crontab_page()
485 if self.run_connect_all_dialog():
486 self.on_connect_all_button_clicked(None)
488 def on_disconnect_all_button_clicked(self, widget):
489 if self.sam_initialized():
490 self.sam_window.on_disconnect_item_activate(None)
491 if self.srvsvc_initialized():
492 self.srvsvc_window.on_disconnect_item_activate(None)
493 if self.regedit_initialized():
494 self.regedit_window.on_disconnect_item_activate(None)
495 if self.svcctl_initialized():
496 self.svcctl_window.on_disconnect_item_activate(None)
497 if self.crontab_initialized():
498 self.crontab_window.on_disconnect_item_activate(None)
499 self.update_sensitivity()
501 def on_connection_info_item_activate(self, widget):
502 #TODO: display connection info (via a dialog or custom window?)
503 self.push_status_message("This is not implemented yet!")
506 def on_clear_log_activate(self, widget):
507 self.messages_textview.get_buffer().set_text("")
510 def on_about_item_activate(self, widget):
511 dialog = AboutDialog(
513 "A tool to display other utilities in a simple, unified window.",
520 def on_quit_item_activate(self, widget):
523 #************ END OF CLASS ***************
526 print "Usage: %s [OPTIONS]" % (str(os.path.split(__file__)[-1]))
527 print "All options are optional. The user will be queried for additional information if needed.\n"
528 print " -s --server\t\tspecify the server to connect to."
529 print " -u --user\t\tspecify the user."
530 print " -p --password\tThe password for the user."
531 print " -t --transport\tTransport type.\n\t\t\t\t0 for RPC, SMB, TCP/IP\n\t\t\t\t1 for RPC, TCP/IP\n\t\t\t\t2 for localhost."
532 print " -c --connect-now\tSkip the connect dialog."
537 try: #get arguments into a nicer format
538 opts, args = getopt.getopt(argv, "chu:s:p:t:", ["help", "user=", "server=", "password=", "connect-now", "transport="])
539 except getopt.GetoptError:
543 for opt, arg in opts:
544 if opt in ("-h", "--help"):
547 elif opt in ("-s", "--server"):
548 arguments.update({"server":arg})
549 elif opt in ("-u", "--user"):
550 arguments.update({"username":arg})
551 elif opt in ("-p", "--password"):
552 arguments.update({"password":arg})
553 elif opt in ("-t", "--transport"):
554 arguments.update({"transport_type":int(arg)})
555 elif opt in ("-c", "--connect-now"):
556 arguments.update({"connect_now":True})
560 if __name__ == "__main__":
561 arguments = ParseArgs(sys.argv[1:])
562 gtk.gdk.threads_init()
563 main_window = SambaUtilities(arguments)
564 sys.stdout = main_window #redirect print statements to the write() function of this class