<s> """<STR_LIT>""" <EOL> from twisted . internet import defer <EOL> from twisted . application import service , internet <EOL> from twisted . python import util <EOL> from twisted . python import log <EOL> from twisted import cred <EOL> import twisted . cred . portal <EOL> from twisted . mail import protocols , smtp <EOL> import os <EOL> from zope . interface import implements , Interface <EOL> class DomainWithDefaultDict : <EOL> '''<STR_LIT>''' <EOL> def __init__ ( self , domains , default ) : <EOL> self . domains = domains <EOL> self . default = default <EOL> def setDefaultDomain ( self , domain ) : <EOL> self . default = domain <EOL> def has_key ( self , name ) : <EOL> return <NUM_LIT:1> <EOL> def fromkeys ( klass , keys , value = None ) : <EOL> d = klass ( ) <EOL> for k in keys : <EOL> d [ k ] = value <EOL> return d <EOL> fromkeys = classmethod ( fromkeys ) <EOL> def __contains__ ( self , name ) : <EOL> return <NUM_LIT:1> <EOL> def __getitem__ ( self , name ) : <EOL> return self . domains . get ( name , self . default ) <EOL> def __setitem__ ( self , name , value ) : <EOL> self . domains [ name ] = value <EOL> def __delitem__ ( self , name ) : <EOL> del self . domains [ name ] <EOL> def __iter__ ( self ) : <EOL> return iter ( self . domains ) <EOL> def __len__ ( self ) : <EOL> return len ( self . domains ) <EOL> def __str__ ( self ) : <EOL> """<STR_LIT>""" <EOL> return '<STR_LIT>' % ( self . domains , ) <EOL> def __repr__ ( self ) : <EOL> """<STR_LIT>""" <EOL> return '<STR_LIT>' % ( self . domains , ) <EOL> def get ( self , key , default = None ) : <EOL> return self . domains . get ( key , default ) <EOL> def copy ( self ) : <EOL> return DomainWithDefaultDict ( self . domains . copy ( ) , self . default ) <EOL> def iteritems ( self ) : <EOL> return self . domains . iteritems ( ) <EOL> def iterkeys ( self ) : <EOL> return self . domains . iterkeys ( ) <EOL> def itervalues ( self ) : <EOL> return self . domains . itervalues ( ) <EOL> def keys ( self ) : <EOL> return self . domains . keys ( ) <EOL> def values ( self ) : <EOL> return self . domains . values ( ) <EOL> def items ( self ) : <EOL> return self . domains . items ( ) <EOL> def popitem ( self ) : <EOL> return self . domains . popitem ( ) <EOL> def update ( self , other ) : <EOL> return self . domains . update ( other ) <EOL> def clear ( self ) : <EOL> return self . domains . clear ( ) <EOL> def setdefault ( self , key , default ) : <EOL> return self . domains . setdefault ( key , default ) <EOL> class IDomain ( Interface ) : <EOL> """<STR_LIT>""" <EOL> def exists ( user ) : <EOL> """<STR_LIT>""" <EOL> def addUser ( user , password ) : <EOL> """<STR_LIT>""" <EOL> def startMessage ( user ) : <EOL> """<STR_LIT>""" <EOL> def getCredentialsCheckers ( ) : <EOL> """<STR_LIT>""" <EOL> class IAliasableDomain ( IDomain ) : <EOL> def setAliasGroup ( aliases ) : <EOL> """<STR_LIT>""" <EOL> def exists ( user , memo = None ) : <EOL> """<STR_LIT>""" <EOL> class BounceDomain : <EOL> """<STR_LIT>""" <EOL> implements ( IDomain ) <EOL> def exists ( self , user ) : <EOL> raise smtp . SMTPBadRcpt ( user ) <EOL> def willRelay ( self , user , protocol ) : <EOL> return False <EOL> def addUser ( self , user , password ) : <EOL> pass <EOL> def startMessage ( self , user ) : <EOL> """<STR_LIT>""" <EOL> raise NotImplementedError ( <EOL> "<STR_LIT>" ) <EOL> def getCredentialsCheckers ( self ) : <EOL> return [ ] <EOL> class FileMessage : <EOL> """<STR_LIT>""" <EOL> implements ( smtp . IMessage ) <EOL> def __init__ ( self , fp , name , finalName ) : <EOL> self . fp = fp <EOL> self . name = name <EOL> self . finalName = finalName <EOL> def lineReceived ( self , line ) : <EOL> self . fp . write ( line + '<STR_LIT:\n>' ) <EOL> def eomReceived ( self ) : <EOL> self . fp . close ( ) <EOL> os . rename ( self . name , self . finalName ) <EOL> return defer . succeed ( self . finalName ) <EOL> def connectionLost ( self ) : <EOL> self . fp . close ( ) <EOL> os . remove ( self . name ) <EOL> class MailService ( service . MultiService ) : <EOL> """<STR_LIT>""" <EOL> queue = None <EOL> domains = None <EOL> portals = None <EOL> aliases = None <EOL> smtpPortal = None <EOL> def __init__ ( self ) : <EOL> service . MultiService . __init__ ( self ) <EOL> self . domains = DomainWithDefaultDict ( { } , BounceDomain ( ) ) <EOL> self . portals = { } <EOL> self . monitor = FileMonitoringService ( ) <EOL> self . monitor . setServiceParent ( self ) <EOL> self . smtpPortal = cred . portal . Portal ( self ) <EOL> def getPOP3Factory ( self ) : <EOL> return protocols . POP3Factory ( self ) <EOL> def getSMTPFactory ( self ) : <EOL> return protocols . SMTPFactory ( self , self . smtpPortal ) <EOL> def getESMTPFactory ( self ) : <EOL> return protocols . ESMTPFactory ( self , self . smtpPortal ) <EOL> def addDomain ( self , name , domain ) : <EOL> portal = cred . portal . Portal ( domain ) <EOL> map ( portal . registerChecker , domain . getCredentialsCheckers ( ) ) <EOL> self . domains [ name ] = domain <EOL> self . portals [ name ] = portal <EOL> if self . aliases and IAliasableDomain . providedBy ( domain ) : <EOL> domain . setAliasGroup ( self . aliases ) <EOL> def setQueue ( self , queue ) : <EOL> """<STR_LIT>""" <EOL> self . queue = queue <EOL> def requestAvatar ( self , avatarId , mind , * interfaces ) : <EOL> if smtp . IMessageDelivery in interfaces : <EOL> a = protocols . ESMTPDomainDelivery ( self , avatarId ) <EOL> return smtp . IMessageDelivery , a , lambda : None <EOL> raise NotImplementedError ( ) <EOL> def lookupPortal ( self , name ) : <EOL> return self . portals [ name ] <EOL> def defaultPortal ( self ) : <EOL> return self . portals [ '<STR_LIT>' ] <EOL> class FileMonitoringService ( internet . TimerService ) : <EOL> def __init__ ( self ) : <EOL> self . files = [ ] <EOL> self . intervals = iter ( util . IntervalDifferential ( [ ] , <NUM_LIT> ) ) <EOL> def startService ( self ) : <EOL> service . Service . startService ( self ) <EOL> self . _setupMonitor ( ) <EOL> def _setupMonitor ( self ) : <EOL> from twisted . internet import reactor <EOL> t , self . index = self . intervals . next ( ) <EOL> self . _call = reactor . callLater ( t , self . _monitor ) <EOL> def stopService ( self ) : <EOL> service . Service . stopService ( self ) <EOL> if self . _call : <EOL> self . _call . cancel ( ) <EOL> self . _call = None <EOL> def monitorFile ( self , name , callback , interval = <NUM_LIT:10> ) : <EOL> try : <EOL> mtime = os . path . getmtime ( name ) <EOL> except : <EOL> mtime = <NUM_LIT:0> <EOL> self . files . append ( [ interval , name , callback , mtime ] ) <EOL> self . intervals . addInterval ( interval ) <EOL> def unmonitorFile ( self , name ) : <EOL> for i in range ( len ( self . files ) ) : <EOL> if name == self . files [ i ] [ <NUM_LIT:1> ] : <EOL> self . intervals . removeInterval ( self . files [ i ] [ <NUM_LIT:0> ] ) <EOL> del self . files [ i ] <EOL> break <EOL> def _monitor ( self ) : <EOL> self . _call = None <EOL> if self . index is not None : <EOL> name , callback , mtime = self . files [ self . index ] [ <NUM_LIT:1> : ] <EOL> try : <EOL> now = os . path . getmtime ( name ) <EOL> except : <EOL> now = <NUM_LIT:0> <EOL> if now > mtime : <EOL> log . msg ( "<STR_LIT>" % ( name , ) ) <EOL> self . files [ self . index ] [ <NUM_LIT:3> ] = now <EOL> callback ( name ) <EOL> self . _setupMonitor ( ) </s>
