<s> """<STR_LIT>""" <EOL> import os <EOL> import re <EOL> import signal as _signal <EOL> import sys <EOL> import time <EOL> import threading <EOL> from cherrypy . _cpcompat import basestring , get_daemon , get_thread_ident , ntob , set , Timer , SetDaemonProperty <EOL> _module__file__base = os . getcwd ( ) <EOL> class SimplePlugin ( object ) : <EOL> """<STR_LIT>""" <EOL> bus = None <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , bus ) : <EOL> self . bus = bus <EOL> def subscribe ( self ) : <EOL> """<STR_LIT>""" <EOL> for channel in self . bus . listeners : <EOL> method = getattr ( self , channel , None ) <EOL> if method is not None : <EOL> self . bus . subscribe ( channel , method ) <EOL> def unsubscribe ( self ) : <EOL> """<STR_LIT>""" <EOL> for channel in self . bus . listeners : <EOL> method = getattr ( self , channel , None ) <EOL> if method is not None : <EOL> self . bus . unsubscribe ( channel , method ) <EOL> class SignalHandler ( object ) : <EOL> """<STR_LIT>""" <EOL> handlers = { } <EOL> """<STR_LIT>""" <EOL> signals = { } <EOL> """<STR_LIT>""" <EOL> for k , v in vars ( _signal ) . items ( ) : <EOL> if k . startswith ( '<STR_LIT>' ) and not k . startswith ( '<STR_LIT>' ) : <EOL> signals [ v ] = k <EOL> del k , v <EOL> def __init__ ( self , bus ) : <EOL> self . bus = bus <EOL> self . handlers = { '<STR_LIT>' : self . bus . exit , <EOL> '<STR_LIT>' : self . handle_SIGHUP , <EOL> '<STR_LIT>' : self . bus . graceful , <EOL> } <EOL> if sys . platform [ : <NUM_LIT:4> ] == '<STR_LIT>' : <EOL> del self . handlers [ '<STR_LIT>' ] <EOL> self . handlers [ '<STR_LIT>' ] = self . bus . graceful <EOL> self . bus . log ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> self . handlers [ '<STR_LIT>' ] = self . _jython_SIGINT_handler <EOL> self . _previous_handlers = { } <EOL> def _jython_SIGINT_handler ( self , signum = None , frame = None ) : <EOL> self . bus . log ( '<STR_LIT>' ) <EOL> self . bus . exit ( ) <EOL> def subscribe ( self ) : <EOL> """<STR_LIT>""" <EOL> for sig , func in self . handlers . items ( ) : <EOL> try : <EOL> self . set_handler ( sig , func ) <EOL> except ValueError : <EOL> pass <EOL> def unsubscribe ( self ) : <EOL> """<STR_LIT>""" <EOL> for signum , handler in self . _previous_handlers . items ( ) : <EOL> signame = self . signals [ signum ] <EOL> if handler is None : <EOL> self . bus . log ( "<STR_LIT>" % signame ) <EOL> handler = _signal . SIG_DFL <EOL> else : <EOL> self . bus . log ( "<STR_LIT>" % ( signame , handler ) ) <EOL> try : <EOL> our_handler = _signal . signal ( signum , handler ) <EOL> if our_handler is None : <EOL> self . bus . log ( "<STR_LIT>" <EOL> "<STR_LIT>" % <EOL> ( signame , handler ) , level = <NUM_LIT:30> ) <EOL> except ValueError : <EOL> self . bus . log ( "<STR_LIT>" % <EOL> ( signame , handler ) , level = <NUM_LIT> , traceback = True ) <EOL> def set_handler ( self , signal , listener = None ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( signal , basestring ) : <EOL> signum = getattr ( _signal , signal , None ) <EOL> if signum is None : <EOL> raise ValueError ( "<STR_LIT>" % signal ) <EOL> signame = signal <EOL> else : <EOL> try : <EOL> signame = self . signals [ signal ] <EOL> except KeyError : <EOL> raise ValueError ( "<STR_LIT>" % signal ) <EOL> signum = signal <EOL> prev = _signal . signal ( signum , self . _handle_signal ) <EOL> self . _previous_handlers [ signum ] = prev <EOL> if listener is not None : <EOL> self . bus . log ( "<STR_LIT>" % signame ) <EOL> self . bus . subscribe ( signame , listener ) <EOL> def _handle_signal ( self , signum = None , frame = None ) : <EOL> """<STR_LIT>""" <EOL> signame = self . signals [ signum ] <EOL> self . bus . log ( "<STR_LIT>" % signame ) <EOL> self . bus . publish ( signame ) <EOL> def handle_SIGHUP ( self ) : <EOL> """<STR_LIT>""" <EOL> if os . isatty ( sys . stdin . fileno ( ) ) : <EOL> self . bus . log ( "<STR_LIT>" ) <EOL> self . bus . exit ( ) <EOL> else : <EOL> self . bus . log ( "<STR_LIT>" ) <EOL> self . bus . restart ( ) <EOL> try : <EOL> import pwd , grp <EOL> except ImportError : <EOL> pwd , grp = None , None <EOL> class DropPrivileges ( SimplePlugin ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , bus , umask = None , uid = None , gid = None ) : <EOL> SimplePlugin . __init__ ( self , bus ) <EOL> self . finalized = False <EOL> self . uid = uid <EOL> self . gid = gid <EOL> self . umask = umask <EOL> def _get_uid ( self ) : <EOL> return self . _uid <EOL> def _set_uid ( self , val ) : <EOL> if val is not None : <EOL> if pwd is None : <EOL> self . bus . log ( "<STR_LIT>" , <EOL> level = <NUM_LIT:30> ) <EOL> val = None <EOL> elif isinstance ( val , basestring ) : <EOL> val = pwd . getpwnam ( val ) [ <NUM_LIT:2> ] <EOL> self . _uid = val <EOL> uid = property ( _get_uid , _set_uid , <EOL> doc = "<STR_LIT>" ) <EOL> def _get_gid ( self ) : <EOL> return self . _gid <EOL> def _set_gid ( self , val ) : <EOL> if val is not None : <EOL> if grp is None : <EOL> self . bus . log ( "<STR_LIT>" , <EOL> level = <NUM_LIT:30> ) <EOL> val = None <EOL> elif isinstance ( val , basestring ) : <EOL> val = grp . getgrnam ( val ) [ <NUM_LIT:2> ] <EOL> self . _gid = val <EOL> gid = property ( _get_gid , _set_gid , <EOL> doc = "<STR_LIT>" ) <EOL> def _get_umask ( self ) : <EOL> return self . _umask <EOL> def _set_umask ( self , val ) : <EOL> if val is not None : <EOL> try : <EOL> os . umask <EOL> except AttributeError : <EOL> self . bus . log ( "<STR_LIT>" , <EOL> level = <NUM_LIT:30> ) <EOL> val = None <EOL> self . _umask = val <EOL> umask = property ( _get_umask , _set_umask , <EOL> doc = """<STR_LIT>""" ) <EOL> def start ( self ) : <EOL> def current_ids ( ) : <EOL> """<STR_LIT>""" <EOL> name , group = None , None <EOL> if pwd : <EOL> name = pwd . getpwuid ( os . getuid ( ) ) [ <NUM_LIT:0> ] <EOL> if grp : <EOL> group = grp . getgrgid ( os . getgid ( ) ) [ <NUM_LIT:0> ] <EOL> return name , group <EOL> if self . finalized : <EOL> if not ( self . uid is None and self . gid is None ) : <EOL> self . bus . log ( '<STR_LIT>' % <EOL> current_ids ( ) ) <EOL> else : <EOL> if self . uid is None and self . gid is None : <EOL> if pwd or grp : <EOL> self . bus . log ( '<STR_LIT>' , level = <NUM_LIT:30> ) <EOL> else : <EOL> self . bus . log ( '<STR_LIT>' % current_ids ( ) ) <EOL> if self . gid is not None : <EOL> os . setgid ( self . gid ) <EOL> os . setgroups ( [ ] ) <EOL> if self . uid is not None : <EOL> os . setuid ( self . uid ) <EOL> self . bus . log ( '<STR_LIT>' % current_ids ( ) ) <EOL> if self . finalized : <EOL> if self . umask is not None : <EOL> self . bus . log ( '<STR_LIT>' % self . umask ) <EOL> else : <EOL> if self . umask is None : <EOL> self . bus . log ( '<STR_LIT>' , level = <NUM_LIT:30> ) <EOL> else : <EOL> old_umask = os . umask ( self . umask ) <EOL> self . bus . log ( '<STR_LIT>' % <EOL> ( old_umask , self . umask ) ) <EOL> self . finalized = True <EOL> start . priority = <NUM_LIT> <EOL> class Daemonizer ( SimplePlugin ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , bus , stdin = '<STR_LIT>' , stdout = '<STR_LIT>' , <EOL> stderr = '<STR_LIT>' ) : <EOL> SimplePlugin . __init__ ( self , bus ) <EOL> self . stdin = stdin <EOL> self . stdout = stdout <EOL> self . stderr = stderr <EOL> self . finalized = False <EOL> def start ( self ) : <EOL> if self . finalized : <EOL> self . bus . log ( '<STR_LIT>' ) <EOL> if threading . activeCount ( ) != <NUM_LIT:1> : <EOL> self . bus . log ( '<STR_LIT>' <EOL> '<STR_LIT>' % <EOL> threading . enumerate ( ) , level = <NUM_LIT:30> ) <EOL> sys . stdout . flush ( ) <EOL> sys . stderr . flush ( ) <EOL> try : <EOL> pid = os . fork ( ) <EOL> if pid == <NUM_LIT:0> : <EOL> pass <EOL> else : <EOL> self . bus . log ( '<STR_LIT>' ) <EOL> os . _exit ( <NUM_LIT:0> ) <EOL> except OSError : <EOL> exc = sys . exc_info ( ) [ <NUM_LIT:1> ] <EOL> sys . exit ( "<STR_LIT>" <EOL> % ( sys . argv [ <NUM_LIT:0> ] , exc . errno , exc . strerror ) ) <EOL> os . setsid ( ) <EOL> try : <EOL> pid = os . fork ( ) <EOL> if pid > <NUM_LIT:0> : <EOL> self . bus . log ( '<STR_LIT>' ) <EOL> os . _exit ( <NUM_LIT:0> ) <EOL> except OSError : <EOL> exc = sys . exc_info ( ) [ <NUM_LIT:1> ] <EOL> sys . exit ( "<STR_LIT>" <EOL> % ( sys . argv [ <NUM_LIT:0> ] , exc . errno , exc . strerror ) ) <EOL> os . chdir ( "<STR_LIT:/>" ) <EOL> os . umask ( <NUM_LIT:0> ) <EOL> si = open ( self . stdin , "<STR_LIT:r>" ) <EOL> so = open ( self . stdout , "<STR_LIT>" ) <EOL> se = open ( self . stderr , "<STR_LIT>" ) <EOL> os . dup2 ( si . fileno ( ) , sys . stdin . fileno ( ) ) <EOL> os . dup2 ( so . fileno ( ) , sys . stdout . fileno ( ) ) <EOL> os . dup2 ( se . fileno ( ) , sys . stderr . fileno ( ) ) <EOL> self . bus . log ( '<STR_LIT>' % os . getpid ( ) ) <EOL> self . finalized = True <EOL> start . priority = <NUM_LIT> <EOL> class PIDFile ( SimplePlugin ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , bus , pidfile ) : <EOL> SimplePlugin . __init__ ( self , bus ) <EOL> self . pidfile = pidfile <EOL> self . finalized = False <EOL> def start ( self ) : <EOL> pid = os . getpid ( ) <EOL> if self . finalized : <EOL> self . bus . log ( '<STR_LIT>' % ( pid , self . pidfile ) ) <EOL> else : <EOL> open ( self . pidfile , "<STR_LIT:wb>" ) . write ( ntob ( "<STR_LIT:%s>" % pid , '<STR_LIT:utf8>' ) ) <EOL> self . bus . log ( '<STR_LIT>' % ( pid , self . pidfile ) ) <EOL> self . finalized = True <EOL> start . priority = <NUM_LIT> <EOL> def exit ( self ) : <EOL> try : <EOL> os . remove ( self . pidfile ) <EOL> self . bus . log ( '<STR_LIT>' % self . pidfile ) <EOL> except ( KeyboardInterrupt , SystemExit ) : <EOL> raise <EOL> except : <EOL> pass <EOL> class PerpetualTimer ( Timer ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> "<STR_LIT>" <EOL> self . bus = kwargs . pop ( '<STR_LIT>' , None ) <EOL> super ( PerpetualTimer , self ) . __init__ ( * args , ** kwargs ) <EOL> def run ( self ) : <EOL> while True : <EOL> self . finished . wait ( self . interval ) <EOL> if self . finished . isSet ( ) : <EOL> return <EOL> try : <EOL> self . function ( * self . args , ** self . kwargs ) <EOL> except Exception : <EOL> if self . bus : <EOL> self . bus . log ( <EOL> "<STR_LIT>" % <EOL> self . function , level = <NUM_LIT> , traceback = True ) <EOL> raise <EOL> class BackgroundTask ( SetDaemonProperty , threading . Thread ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , interval , function , args = [ ] , kwargs = { } , bus = None ) : <EOL> threading . Thread . __init__ ( self ) <EOL> self . interval = interval <EOL> self . function = function <EOL> self . args = args <EOL> self . kwargs = kwargs <EOL> self . running = False <EOL> self . bus = bus <EOL> self . daemon = True <EOL> def cancel ( self ) : <EOL> self . running = False <EOL> def run ( self ) : <EOL> self . running = True <EOL> while self . running : <EOL> time . sleep ( self . interval ) <EOL> if not self . running : <EOL> return <EOL> try : <EOL> self . function ( * self . args , ** self . kwargs ) <EOL> except Exception : <EOL> if self . bus : <EOL> self . bus . log ( "<STR_LIT>" <EOL> % self . function , level = <NUM_LIT> , traceback = True ) <EOL> raise <EOL> class Monitor ( SimplePlugin ) : <EOL> """<STR_LIT>""" <EOL> callback = None <EOL> """<STR_LIT>""" <EOL> frequency = <NUM_LIT> <EOL> """<STR_LIT>""" <EOL> thread = None <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , bus , callback , frequency = <NUM_LIT> , name = None ) : <EOL> SimplePlugin . __init__ ( self , bus ) <EOL> self . callback = callback <EOL> self . frequency = frequency <EOL> self . thread = None <EOL> self . name = name <EOL> def start ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . frequency > <NUM_LIT:0> : <EOL> threadname = self . name or self . __class__ . __name__ <EOL> if self . thread is None : <EOL> self . thread = BackgroundTask ( self . frequency , self . callback , <EOL> bus = self . bus ) <EOL> self . thread . setName ( threadname ) <EOL> self . thread . start ( ) <EOL> self . bus . log ( "<STR_LIT>" % threadname ) <EOL> else : <EOL> self . bus . log ( "<STR_LIT>" % threadname ) <EOL> start . priority = <NUM_LIT> <EOL> def stop ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . thread is None : <EOL> self . bus . log ( "<STR_LIT>" % self . name or self . __class__ . __name__ ) <EOL> else : <EOL> if self . thread is not threading . currentThread ( ) : <EOL> name = self . thread . getName ( ) <EOL> self . thread . cancel ( ) <EOL> if not get_daemon ( self . thread ) : <EOL> self . bus . log ( "<STR_LIT>" % name ) <EOL> self . thread . join ( ) <EOL> self . bus . log ( "<STR_LIT>" % name ) <EOL> self . thread = None <EOL> def graceful ( self ) : <EOL> """<STR_LIT>""" <EOL> self . stop ( ) <EOL> self . start ( ) <EOL> class Autoreloader ( Monitor ) : <EOL> """<STR_LIT>""" <EOL> files = None <EOL> """<STR_LIT>""" <EOL> frequency = <NUM_LIT:1> <EOL> """<STR_LIT>""" <EOL> match = '<STR_LIT>' <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , bus , frequency = <NUM_LIT:1> , match = '<STR_LIT>' ) : <EOL> self . mtimes = { } <EOL> self . files = set ( ) <EOL> self . match = match <EOL> Monitor . __init__ ( self , bus , self . run , frequency ) <EOL> def start ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . thread is None : <EOL> self . mtimes = { } <EOL> Monitor . start ( self ) <EOL> start . priority = <NUM_LIT> <EOL> def sysfiles ( self ) : <EOL> """<STR_LIT>""" <EOL> files = set ( ) <EOL> for k , m in sys . modules . items ( ) : <EOL> if re . match ( self . match , k ) : <EOL> if hasattr ( m , '<STR_LIT>' ) and hasattr ( m . __loader__ , '<STR_LIT>' ) : <EOL> f = m . __loader__ . archive <EOL> else : <EOL> f = getattr ( m , '<STR_LIT>' , None ) <EOL> if f is not None and not os . path . isabs ( f ) : <EOL> f = os . path . normpath ( os . path . join ( _module__file__base , f ) ) <EOL> files . add ( f ) <EOL> return files <EOL> def run ( self ) : <EOL> """<STR_LIT>""" <EOL> for filename in self . sysfiles ( ) | self . files : <EOL> if filename : <EOL> if filename . endswith ( '<STR_LIT>' ) : <EOL> filename = filename [ : - <NUM_LIT:1> ] <EOL> oldtime = self . mtimes . get ( filename , <NUM_LIT:0> ) <EOL> if oldtime is None : <EOL> continue <EOL> try : <EOL> mtime = os . stat ( filename ) . st_mtime <EOL> except OSError : <EOL> mtime = None <EOL> if filename not in self . mtimes : <EOL> self . mtimes [ filename ] = mtime <EOL> else : <EOL> if mtime is None or mtime > oldtime : <EOL> self . bus . log ( "<STR_LIT>" % filename ) <EOL> self . thread . cancel ( ) <EOL> self . bus . log ( "<STR_LIT>" % self . thread . getName ( ) ) <EOL> self . bus . restart ( ) <EOL> return <EOL> class ThreadManager ( SimplePlugin ) : <EOL> """<STR_LIT>""" <EOL> threads = None <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , bus ) : <EOL> self . threads = { } <EOL> SimplePlugin . __init__ ( self , bus ) <EOL> self . bus . listeners . setdefault ( '<STR_LIT>' , set ( ) ) <EOL> self . bus . listeners . setdefault ( '<STR_LIT>' , set ( ) ) <EOL> self . bus . listeners . setdefault ( '<STR_LIT>' , set ( ) ) <EOL> self . bus . listeners . setdefault ( '<STR_LIT>' , set ( ) ) <EOL> def acquire_thread ( self ) : <EOL> """<STR_LIT>""" <EOL> thread_ident = get_thread_ident ( ) <EOL> if thread_ident not in self . threads : <EOL> i = len ( self . threads ) + <NUM_LIT:1> <EOL> self . threads [ thread_ident ] = i <EOL> self . bus . publish ( '<STR_LIT>' , i ) <EOL> def release_thread ( self ) : <EOL> """<STR_LIT>""" <EOL> thread_ident = get_thread_ident ( ) <EOL> i = self . threads . pop ( thread_ident , None ) <EOL> if i is not None : <EOL> self . bus . publish ( '<STR_LIT>' , i ) <EOL> def stop ( self ) : <EOL> """<STR_LIT>""" <EOL> for thread_ident , i in self . threads . items ( ) : <EOL> self . bus . publish ( '<STR_LIT>' , i ) <EOL> self . threads . clear ( ) <EOL> graceful = stop </s>
