#!/usr/bin/env python
"""

python ThreadedAppServerService.py --username mydomain\myusername --password mypassword --startup auto install

And finally, to uninstall the service, stop it and then run:

python ThreadedAppServerService.py remove

"""
import win32serviceutil
import win32service
import os, sys, cStringIO
import time
import ConfigParser

# With win32all version 163, I found that calling signal.signal crashes a service.  So
# we sneakily replace signal.signal with a no-op.
import signal
def dummy_signal(*args, **kwargs):
	pass
		
signal.signal = dummy_signal

class InitializationError(Exception):
    pass

class EventMailService(win32serviceutil.ServiceFramework):
    _svc_name_ = _svc_display_name_ = ''
    
    ServiceConfigFile = 'sentai\\EventMail.cfg'
    Cfg = ConfigParser.ConfigParser()
    Cfg.read(ServiceConfigFile)
    try:
        ## this has to be wrapped in a try block because it does not seem to
        ## work properly when the service is started.
        ## Works fine when the service is being registered or removed however.
        _svc_name_ = Cfg.get('ServiceName', 'name')
        _svc_display_name_ = Cfg.get('ServiceName', 'name')
    except:
        pass

    _the_app = None

    def __init__(self, args):
        win32serviceutil.ServiceFramework.__init__(self, args)
	# Fix the current working directory -- this gets initialized incorrectly
	# for some reason when run as an NT service.
        self._the_app = None
	try:
	    os.chdir(os.path.abspath(os.path.dirname(__file__)))
        except:
	    pass
	## end

    def SvcStop(self):
        # Before we do anything, tell the SCM we are starting the stop process
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        self._the_app.shutDown()
        ## end
		
    def SvcDoRun(self):
        import servicemanager
        try:
            # Temporarily suck up stdout and stderr into a cStringIO
            stdoutAndStderr = cStringIO.StringIO()
            sys.stdout = sys.stderr = stdoutAndStderr
            if '' not in sys.path:
                sys.path = [''] + sys.path

            ## this can be redirected to a file if we need to capture any of the
            ## print statements. Ideally, this should not be needed.
            sys.stdout = sys.stderr = open('nul', 'w')
            del stdoutAndStderr

            ## now read the extra path information and add it to the system path
            self.Cfg = ConfigParser.ConfigParser()
            self.Cfg.read(self.ServiceConfigFile)
            sourcePath = self.Cfg.get('ExtraPathInfo', 'source')
            shipPath = self.Cfg.get('ExtraPathInfo', 'shipping')
            sys.path.append(sourcePath)
            sys.path.append(shipPath)
        
            ## This part has to be customized for each application
            from EventMail import EventMonitor
            self._the_app = EventMonitor()
            self._the_app.Monitor()
            ## end customization
            
        except InitializationError, e:
            em = 'Initialization file was not properly configured ' + str(self.__class__.__name__)
            servicemanager.LogInfoMsg(str(em))
            f = open('init_error.txt', 'a')
	    f.write(str(time.ctime()) + '\n')
            f.write(str(e) + '\n')
            f.write(self.Cfg.sections() + '\n')
            f.flush()
            f.close()
        except Exception, e:
            servicemanager.LogInfoMsg(str(e))
            f = open('service_error.txt', 'a')
	    f.write(str(time.ctime()) + '\n')
            f.write(str(e) + '\n')
            f.flush()
            f.close()
        ## end

if __name__=='__main__':
	win32serviceutil.HandleCommandLine(EventMailService)
	
