Package web2py :: Package gluon :: Module winservice |
[hide private]
[frames] | no frames]

# Source Code for Module web2py.gluon.winservice

      1  #!/usr/bin/env python
      2  # -*- coding: utf-8 -*-
      3  """
      4  This file is part of the web2py Web Framework
      5  Developed by Massimo Di Pierro <mdipierro@cs.depaul.edu> and
      6  Limodou <limodou@gmail.com>.
      7  License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html)
      8
      9  This makes uses of the pywin32 package
     10  (http://sourceforge.net/projects/pywin32/).
     11  You do not need to install this package to use web2py.
     12
     13
     14  """
     15
     16  import time
     17  import os
     18  import sys
     19  import traceback
     20  try:
     21      import win32serviceutil
     22      import win32service
     23      import win32event
     24  except:
     25      if os.name == 'nt':
     26          print "Warning, winservice is unable to install the Mark Hammond Win32 extensions"
     27  import servicemanager
     28  import _winreg
     29  from fileutils import up
     30
     31  __all__ = ['web2py_windows_service_handler']
     32
     33 -class Service(win32serviceutil.ServiceFramework):
     34
     35      _svc_name_ = '_unNamed'
     36      _svc_display_name_ = '_Service Template'
     37
     38 -    def __init__(self, *args):
     39          win32serviceutil.ServiceFramework.__init__(self, *args)
     40          self.stop_event = win32event.CreateEvent(None, 0, 0, None)
     41
     42 -    def log(self, msg):
     43          servicemanager.LogInfoMsg(str(msg))
     44
     45 -    def SvcDoRun(self):
     46          self.ReportServiceStatus(win32service.SERVICE_START_PENDING)
     47          try:
     48              self.ReportServiceStatus(win32service.SERVICE_RUNNING)
     49              self.start()
     50              win32event.WaitForSingleObject(self.stop_event,
     51                      win32event.INFINITE)
     52          except:
     53              self.log(traceback.format_exc(sys.exc_info))
     54              self.SvcStop()
     55          self.ReportServiceStatus(win32service.SERVICE_STOPPED)
     56
     57 -    def SvcStop(self):
     58          self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
     59          try:
     60              self.stop()
     61          except:
     62              self.log(traceback.format_exc(sys.exc_info))
     63          win32event.SetEvent(self.stop_event)
     64          self.ReportServiceStatus(win32service.SERVICE_STOPPED)
     65
     66      # to be overridden
     67
     68 -    def start(self):
     69          pass
     70
     71      # to be overridden
     72
     73 -    def stop(self):
     74          pass
     75
     76
     77 -class Web2pyService(Service):
     78
     79      _svc_name_ = 'web2py'
     80      _svc_display_name_ = 'web2py Service'
     81      _exe_args_ = 'options'
     82      server = None
     83
     84 -    def chdir(self):
     85          try:
     86              h = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,
     87                                  r'SYSTEM\CurrentControlSet\Services\%s'
     88                                   % self._svc_name_)
     89              try:
     90                  cls = _winreg.QueryValue(h, 'PythonClass')
     91              finally:
     92                  _winreg.CloseKey(h)
     93              dir = os.path.dirname(cls)
     94              os.chdir(dir)
     95              return True
     96          except:
     97              self.log("Can't change to web2py working path; server is stopped")
     98              return False
     99
    100 -    def start(self):
    101          self.log('web2py server starting')
    102          if not self.chdir():
    103              return
    104          if len(sys.argv) == 2:
    105              opt_mod = sys.argv[1]
    106          else:
    107              opt_mod = self._exe_args_
    108          options = __import__(opt_mod, [], [], '')
    109          if True: # legacy support for old options files, which have only (deprecated) numthreads
    110              if hasattr(options, 'numthreads') and not hasattr(options, 'minthreads'):
    111                  options.minthreads = options.numthreads
    112              if not hasattr(options, 'minthreads'): options.minthreads = None
    113              if not hasattr(options, 'maxthreads'): options.maxthreads = None
    114          import main
    115          self.server = main.HttpServer(
    116              ip=options.ip,
    117              port=options.port,
    118              password=options.password,
    119              pid_filename=options.pid_filename,
    120              log_filename=options.log_filename,
    121              profiler_filename=options.profiler_filename,
    122              ssl_certificate=options.ssl_certificate,
    123              ssl_private_key=options.ssl_private_key,
    124              min_threads=options.minthreads,
    125              max_threads=options.maxthreads,
    126              server_name=options.server_name,
    127              request_queue_size=options.request_queue_size,
    128              timeout=options.timeout,
    129              shutdown_timeout=options.shutdown_timeout,
    130              path=options.folder
    131              )
    132          try:
    133              self.server.start()
    134          except:
    135
    136              # self.server.stop()
    137
    138              self.server = None
    139              raise
    140
    141 -    def stop(self):
    142          self.log('web2py server stopping')
    143          if not self.chdir():
    144              return
    145          if self.server:
    146              self.server.stop()
    147          time.sleep(1)
    148
    149
    150 -def web2py_windows_service_handler(argv=None, opt_file='options'):
    151      path = os.path.dirname(__file__)
    152      classstring = os.path.normpath(os.path.join(up(path),
    153                                     'gluon.winservice.Web2pyService'))
    154      if opt_file:
    155          Web2pyService._exe_args_ = opt_file
    156          win32serviceutil.HandleCommandLine(Web2pyService,
    157                  serviceClassString=classstring, argv=['', 'install'])
    158      win32serviceutil.HandleCommandLine(Web2pyService,
    159              serviceClassString=classstring, argv=argv)
    160
    161
    162  if __name__ == '__main__':
    163      web2py_windows_service_handler()
    164