D7net
Home
Console
Upload
information
Create File
Create Folder
About
Tools
:
/
opt
/
lampp
/
share
/
xampp-control-panel
/
Filename :
xampp-control-panel.py
back
Copy
#!/usr/bin/env python # -*- coding: UTF8 -*- # # XAMPP Control Panel # Written by Jono Bacon (jono@jonobacon.org) # # Licensed under the GNU Public License v2 # This program is free software. See the included LICENSE file for details. # # Python module xampp-control-panel.py # Autogenerated from xampp-control-panel.glade # Generated on Wed Aug 24 00:37:20 2005 # Warning: Do not delete or modify comments related to context # They are required to keep user's code import os import gtk import commands import posix import ConfigParser import threading import gobject from socket import gethostname from SimpleGladeApp import SimpleGladeApp from pyinotify import WatchManager, Notifier, ThreadedNotifier, EventsCodes, ProcessEvent __author__ = "nemesis@bluesunset.de" __version__ = "0.8.0" glade_dir = "" WS = "apache" DB = "mysql" FTP = "proftpd" RUN = "RUNNING" STOP = "STOPPED" APACHEPID = "httpd.pid" PROFTPDPID = "proftpd.pid" MYSQLPID = gethostname() + ".pid" class MainWindow(SimpleGladeApp): def __init__(self, path="xampp-control-panel.glade", root="MainWindow", domain=None, **kwargs): path = os.path.join(glade_dir, path) SimpleGladeApp.__init__(self, path, root, domain, **kwargs) # default location of config file for this user (~/.xampp_cp); # config file has format specified for ConfigParser module, e.g. # [main] # xampp_path=/opt/lampp self.CONFIG_FILE_PATH = posix.environ['HOME'] + "/.xampp_cp" # set up the stop buttons that are hidden at the start - the execute buttons were created in glade :) self.mainStopButton = gtk.Button(None, gtk.STOCK_MEDIA_STOP) self.mainStopButton.set_border_width(5) self.mainStopButton.connect("clicked", self.on_mainStopButton_clicked) self.vbox1.pack_start(self.mainStopButton, True, False) self.vbox1.reorder_child(self.mainStopButton, 0) self.mainStopButton.hide() self.apacheStopButton = gtk.Button(None, gtk.STOCK_MEDIA_STOP) self.apacheStopButton.set_border_width(0) self.apacheStopButton.connect("clicked", self.on_apacheStopButton_clicked) self.table1.attach(self.apacheStopButton, 2, 3, 0, 1) self.apacheStopButton.hide() self.mysqlStopButton = gtk.Button(None, gtk.STOCK_MEDIA_STOP) self.mysqlStopButton.set_border_width(0) self.mysqlStopButton.connect("clicked", self.on_mysqlStopButton_clicked) self.table1.attach(self.mysqlStopButton, 2, 3, 1, 2) self.mysqlStopButton.hide() self.proftpdStopButton = gtk.Button(None, gtk.STOCK_MEDIA_STOP) self.proftpdStopButton.set_border_width(0) self.proftpdStopButton.connect("clicked", self.on_proftpdStopButton_clicked) self.table1.attach(self.proftpdStopButton, 2, 3, 2, 3) self.proftpdStopButton.hide() # get path configuration from .xcp file xampppath = self.get_xampp_path() if xampppath == "": self.set_xampp_path("/opt/lampp") # initialise the interface self.init_interface() def get_xampp_path(self): """ get the path info from the config file, or return "" if not set yet """ xampp_path = "" config_parser = self.get_config_parser() if config_parser.has_option('main', 'xampp_path'): xampp_path = config_parser.get('main', 'xampp_path') return xampp_path def set_xampp_path(self, path_to_xampp): """ set the path info in the config file """ config_parser = self.get_config_parser() if not config_parser.has_section('main'): config_parser.add_section('main') config_parser.set('main', 'xampp_path', path_to_xampp) config_parser.write(file(self.CONFIG_FILE_PATH, 'w')) def get_xampp_command(self, command): """ return a string representing a call to the xampp script """ xampp_script = os.path.join(self.get_xampp_path(), "lampp") xampp_command = "%s %s" % (xampp_script, command) return xampp_command def get_config_parser(self): """ get a ConfigParser instance; will create the config file if it doesn't already exist""" if not os.path.exists(self.CONFIG_FILE_PATH): config_file = open(self.CONFIG_FILE_PATH, 'w') config_file.close() config_parser = ConfigParser.ConfigParser() config_parser.readfp(open(self.CONFIG_FILE_PATH)) return config_parser def get_statuses(self): """ get a dictionary of service statues by calling "lampp statusraw"; Returns a dictionary like this: {'APACHE':'RUNNING', 'MYSQL':'NOTRUNNING', 'PROFTPD':'DEACTIVATED'} """ statuses = {} raw_status = commands.getoutput(self.get_xampp_command("statusraw")) lines = raw_status.split("\n") # ignore first line, and create a dictionary of service/status # pairs by splitting each line around the central whitespace statuses = dict([line.split(" ") for line in lines[1:]]) return statuses def init_interface(self): """ set interface buttons and labels for all services if there's already one running""" all_statuses = self.get_statuses() self.running = 0 for service in all_statuses: if all_statuses[service] == RUN: self.running += 1 self.main_stopbutton("show") self.set_interface_for_service(service.lower(), RUN) def set_interface_for_service(self, service, status): if service == WS: execute_btn = self.apacheExButton stop_btn = self.apacheStopButton status_label = self.apacheStatus elif service == DB: execute_btn = self.mysqlExButton stop_btn = self.mysqlStopButton status_label = self.mysqlStatus elif service == FTP: execute_btn = self.proftpdExButton stop_btn = self.proftpdStopButton status_label = self.proftpdStatus if status == RUN: execute_btn.hide() stop_btn.show() status_label.set_text(RUN) elif status == STOP: execute_btn.show() stop_btn.hide() status_label.set_text(STOP) def main_stopbutton(self, status=None): if status == "show": self.mainStopButton.show() self.mainStartButton.hide() else: self.mainStopButton.hide() self.mainStartButton.show() # button handlers def on_mainStartButton_clicked(self, widget, *args): os.popen(self.get_xampp_command("start")) def on_mainStopButton_clicked(self, widget, *args): os.popen(self.get_xampp_command("stop")) def on_apacheButton_clicked(self, widget, *args): os.popen(self.get_xampp_command("start" + WS)) def on_apacheStopButton_clicked(self, widget, *args): os.popen(self.get_xampp_command("stop" + WS)) def on_mysqlButton_clicked(self, widget, *args): os.popen(self.get_xampp_command("start" + DB)) def on_mysqlStopButton_clicked(self, widget, *args): os.popen(self.get_xampp_command("stop" + DB)) def on_proftpdButton_clicked(self, widget, *args): os.popen(self.get_xampp_command("startftp")) # ftp, not proftpd! def on_proftpdStopButton_clicked(self, widget, *args): os.popen(self.get_xampp_command("stopftp")) # dito def on_prefsButton_clicked(self, widget, *args): print "Preferences clicked" self.prefsswindow = PrefsWindow("xampp-control-panel.glade", "PrefsWindow", parent=self) def on_cancelButton_clicked(self, widget, *args): print "Quitting" self.gtk_main_quit() class PrefsWindow(SimpleGladeApp): def __init__(self, path="xamppcontrolpanel.glade", root="PrefsWindow", domain=None, **kwargs): path = os.path.join(glade_dir, path) SimpleGladeApp.__init__(self, path, root, domain, **kwargs) self.pathTextBox.set_text(self.parent.get_xampp_path()) def on_browseButton_clicked(self, widget, *args): """ handler for file chooser - select path to XAMPP installation """ fc = gtk.FileChooserDialog( title = 'Select the XAMPP installation directory', action = gtk.FILE_CHOOSER_ACTION_OPEN, buttons = (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK) ) fc.set_filename(self.pathTextBox.get_text()) response = fc.run() if response == gtk.RESPONSE_OK: self.pathTextBox.set_text(fc.get_filename()) fc.destroy() def on_applyButton_clicked(self, widget, *args): self.client.set_string("/apps/xampp-control-panel/xampp-path", self.pathTextBox.get_text()) xampppath = self.get_xampp_path() if xampppath == "": self.parent.apacheExButton.set_sensitive(False) self.parent.mysqlExButton.set_sensitive(False) self.parent.proftpdExButton.set_sensitive(False) else: self.parent.apacheExButton.set_sensitive(True) self.parent.mysqlExButton.set_sensitive(True) self.parent.proftpdExButton.set_sensitive(True) self.PrefsWindow.destroy() def on_cancelButton_clicked(self, widget, *args): print "on_cancelButton_clicked called with self.%s" % widget.get_name() self.PrefsWindow.destroy() class PXampp(ProcessEvent): def __init__(self): self.mw = main_window self.running = self.mw.running def process_IN_CREATE(self, event): if event.name == APACHEPID: self.running += 1 self.mw.set_interface_for_service(WS, RUN) elif event.name == MYSQLPID: self.running += 1 self.mw.set_interface_for_service(DB, RUN) elif event.name == PROFTPDPID: self.running += 1 self.mw.set_interface_for_service(FTP, RUN) if self.running >= 1: self.mw.main_stopbutton("show") def process_IN_DELETE(self, event): if event.name == APACHEPID: self.running -= 1 self.mw.set_interface_for_service(WS, STOP) elif event.name == MYSQLPID: self.running -= 1 self.mw.set_interface_for_service(DB, STOP) elif event.name == PROFTPDPID: self.running -= 1 self.mw.set_interface_for_service(FTP, STOP) if self.running == 0: self.mw.main_stopbutton() # should normaly never happen elif self.running < 0: self.mw.init_interface() class StatusMonitor(threading.Thread): """ Thread which runs in the background and updates the interface based on pyinotify. Linux Kernel 2.6.13+ are required!""" def __init__(self): super(StatusMonitor, self).__init__() self.quit = False self.wm = WatchManager() # watched events self.mask = 0x00000100 | 0x00000200 self.notifier = Notifier(self.wm, PXampp()) self._lampp = main_window.get_xampp_path() wdd = self.wm.add_watch([ os.path.join(self._lampp, 'logs/'),#httpd.pid os.path.join(self._lampp, 'var/mysql/'), #hostname.pid os.path.join(self._lampp, 'var/')], #proftpd.pid self.mask) def run(self): while not self.quit: try: # process the queue of events self.notifier.process_events() if self.notifier.check_events(): # read notified events and enqeue them self.notifier.read_events() # you can do some tasks here... except KeyboardInterrupt: print 'stop monitoring...' # destroy the inotify's instance on this interrupt (stop monitoring) self.notifier.stop() except Exception, err: # otherwise keep on looping pass print 'stop monitoring...' # destroy the inotify's instance on this interrupt (stop monitoring) self.notifier.stop() if __name__ == "__main__": gobject.threads_init() main_window = MainWindow() sm = StatusMonitor() sm.start() main_window.run() sm.quit = True