class Toaster(Item): implements(IBreadConsumer) powerupInterfaces = (IAppliance, IBreadConsumer) powerStrip = dependency.dependsOn(PowerStrip, lambda ps: ps.setForUSElectricity(), doc="the power source for this toaster") description = text() breadFactory = dependency.dependsOn( Breadbox, doc="the thing we get bread input from", whenDeleted=reference.CASCADE) callback = inmemory() def activate(self): self.callback = None def installed(self): if self.callback is not None: self.callback("installed") def uninstalled(self): if self.callback is not None: self.callback("uninstalled") def toast(self): self.powerStrip.draw(100) self.breadFactory.dispenseBread(2)
class SpambayesFilter(item.Item): """ Spambayes-based L{iquotient.IHamFilter} powerup. """ implements(iquotient.IHamFilter) schemaVersion = 3 classifier = attributes.inmemory() guesser = attributes.inmemory() filter = dependsOn(Filter) powerupInterfaces = (iquotient.IHamFilter, ) def _classifierPath(self): return self.store.newFilePath('spambayes-%d-classifier.sqlite' % (self.storeID, )) def activate(self): self.classifier = _SQLite3Classifier(self._classifierPath().path) self.guesser = hammie.Hammie(self.classifier, mode='r') # IHamFilter def classify(self, item): # SpamBayes thinks 0 is ham, 1 is spam. We have a different idea. score = 1.0 - self.guesser.score(item.impl.source.open()) return score <= SPAM_THRESHHOLD, score def train(self, spam, item): """ Train the classifier. @param spam: A boolean indicating whether C{item} is spam or not. @param item: A Message to train with. """ for i in xrange(10): self.guesser.train(item.impl.source.open(), spam) if spam: if self.classify(item) < SPAM_THRESHHOLD: break else: if self.classify(item) > SPAM_THRESHHOLD: break def forgetTraining(self): p = self._classifierPath() if p.exists(): p.remove() self.activate()
class TCPPort(PortMixin, Item): """ An Axiom Service Item which will bind a TCP port to a protocol factory when it is started. """ schemaVersion = 2 portNumber = integer(doc=""" The TCP port number on which to listen. """) interface = text(doc=""" The hostname to bind to. """, default=u'') factory = reference(doc=""" An Item with a C{getFactory} method which returns a Twisted protocol factory. """, whenDeleted=reference.CASCADE) parent = inmemory(doc=""" A reference to the parent service of this service, whenever there is a parent. """) _listen = inmemory(doc=""" An optional reference to a callable implementing the same interface as L{IReactorTCP.listenTCP}. If set, this will be used to bind a network port. If not set, the reactor will be imported and its C{listenTCP} method will be used. """) listeningPort = inmemory(doc=""" A reference to the L{IListeningPort} returned by C{self.listen} which is set whenever there there is one listening. """) def listen(self): if self._listen is not None: _listen = self._listen else: from twisted.internet import reactor _listen = reactor.listenTCP return _listen(self.portNumber, self.factory.getFactory(), interface=self.interface.encode('ascii'))
class RemoteStatsObserver(item.Item): """ Obsolete. Only present for schema compatibility. Do not use. """ hostname = attributes.bytes(doc="A host to send stat updates to") port = attributes.integer(doc="The port to send stat updates to") protocol = attributes.inmemory(doc="The juice protocol instance to send stat updates over")
class Sword(ActivateHelper, Item): typeName = 'test_app_sword' schemaVersion = 2 name = text() damagePerHit = integer() owner = reference() activated = inmemory()
class InventoryEntry(ActivateHelper, Item): typeName = 'test_app_inv' schemaVersion = 1 owner = reference() owned = reference() activated = inmemory()
class SubStore(Item): schemaVersion = 1 typeName = 'substore' storepath = path() substore = inmemory() implements(IPowerupIndirector) def createNew(cls, store, pathSegments): """ Create a new SubStore, allocating a new file space for it. """ storepath = store.newDirectory(*pathSegments) self = cls(store=store, storepath=storepath) self.open() self.close() return self createNew = classmethod(createNew) def close(self): self.substore.close() del self.substore._openSubStore del self.substore def open(self, debug=False): if hasattr(self, 'substore'): return self.substore else: s = self.substore = Store(self.storepath.path, parent=self.store, idInParent=self.storeID, debug=debug) s._openSubStore = self # don't fall out of cache as long as the # store is alive! return s def __conform__(self, interface): """ I adapt my store object to whatever interface I am adapted to. This allows for avatar adaptation in L{axiom.userbase} to work properly without having to know explicitly that all 'avatars' objects are SubStore instances, since it is valid to have non-SubStore avatars, which are simply adaptable to the cred interfaces they represent. """ ifa = interface(self.open(debug=self.store.debug), None) return ifa def indirect(self, interface): """ Like __conform__, I adapt my store to whatever interface I am asked to produce a powerup for. This allows for app stores to be installed as powerups for their site stores directly, rather than having an additional item type for each interface that we might wish to adapt to. """ return interface(self)
class SIPDispatcherService(Item, Service): typeName = 'sine_sipdispatcher_service' schemaVersion = 3 portno = integer(default=5060) parent = inmemory() running = inmemory() name = inmemory() dispatcher = inmemory() proxy = inmemory() port = inmemory() site = inmemory() userbase = dependsOn(LoginSystem) powerupInterfaces = (IService, ) def privilegedStartService(self): portal = Portal(self.userbase, [self.userbase]) self.proxy = sip.Proxy(portal) self.dispatcher = sip.SIPDispatcher(portal, self.proxy) f = sip.SIPTransport(self.dispatcher, getHostnames(self.store), self.portno) self.port = reactor.listenUDP(self.portno, f)
class AMPConfiguration(Item): """ Configuration object for a Mantissa AMP server. @ivar ONE_TIME_PAD_DURATION: The duration of each one-time pad, in seconds. @type ONE_TIME_PAD_DURATION: C{int} """ powerupInterfaces = (IProtocolFactoryFactory, IOneTimePadGenerator) implements(*powerupInterfaces) schemaVersion = 2 loginSystem = dependsOn(LoginSystem) _oneTimePads = inmemory() ONE_TIME_PAD_DURATION = 60 * 2 callLater = staticmethod(reactor.callLater) def activate(self): """ Initialize L{_oneTimePads} """ self._oneTimePads = {} # IOneTimePadGenerator def generateOneTimePad(self, userStore): """ Generate a pad which can be used to authenticate via AMP. This pad will expire in L{ONE_TIME_PAD_DURATION} seconds. """ pad = secureRandom(16).encode('hex') self._oneTimePads[pad] = userStore.idInParent def expirePad(): self._oneTimePads.pop(pad, None) self.callLater(self.ONE_TIME_PAD_DURATION, expirePad) return pad # IProtocolFactoryFactory def getFactory(self): """ Return a server factory which creates AMP protocol instances. """ factory = ServerFactory() def protocol(): proto = CredReceiver() proto.portal = Portal( self.loginSystem, [self.loginSystem, OneTimePadChecker(self._oneTimePads)]) return proto factory.protocol = protocol return factory
class HookRunner(Item): """ Runnable that simply calls a supplied hook. """ ignored = integer() hook = inmemory() def run(self): self.hook(self)
class TestService(item.Item, Service): typeName = 'sine_tpcc_test_service' schemaVersion = 1 installedOn = attributes.reference() parent = attributes.inmemory() running = attributes.inmemory() name = attributes.inmemory() dispatcherSvc = attributes.reference() powerupInterfaces = (IService,) def startService(self): print "YAY" self.dispatcherSvc.setupCallBetween( ("Confession Hotline (watt)", sip.URL("watt.divmod.com", "confession"), {},), ("Some Bozo", sip.URL("divmod.com", "washort"), {}), )
class UniversalEndpointService(item.Item): """ """ typeName = 'mantissa_q2q_service' schemaVersion = 1 q2qPortNumber = attributes.integer(default=8787) inboundTCPPortNumber = attributes.integer(default=None) publicIP = attributes.integer(default=None) udpEnabled = attributes.integer(default=False) certificatePath = attributes.path(default=None) _svcInst = attributes.inmemory() def __init__(self, **kw): super(UniversalEndpointService, self).__init__(**kw) if self.certificatePath is None: self.certificatePath = self.store.newDirectory( str(self.storeID), 'certificates') if not self.certificatePath.exists(): self.certificatePath.makedirs() def activate(self): self._svcInst = None def _makeService(self): self._svcInst = q2qclient.ClientQ2QService( self.certificatePath.path, publicIP=self.publicIP, inboundTCPPortnum=self.inboundTCPPortNumber, udpEnabled=self.udpEnabled, ) def _getService(self): if self._svcInst is None: self._makeService() return self._svcInst def installOn(self, other): other.powerUp(self, ixmantissa.IQ2QService) def listenQ2Q(self, fromAddress, protocolsToFactories, serverDescription): return self._getService().listenQ2Q(fromAddress, protocolsToFactories, serverDescription) def connectQ2Q(self, fromAddress, toAddress, protocolName, protocolFactory, usePrivateCertificate=None, fakeFromDomain=None, chooser=None): return self._getService().connectQ2Q(fromAddress, toAddress, protocolName, protocolFactory, usePrivateCertificate, fakeFromDomain, chooser)
class MockComposer(item.Item): """ Mock L{compose.Composer} that we use to test L{smtpout.MessageDelivery}. """ _ignored = attributes.integer() log = attributes.inmemory() def messageBounced(self, log, toAddress, message): self.log.append((log, toAddress, message.storeID))
class PersistedMailer(item.Item): """ A persisted mailer. """ endpoint = attributes.reference() credentials = attributes.reference() indirected = attributes.inmemory() def activate(self): endpoint = self.endpoint.instantiate() self.indirected = mailer.Mailer(endpoint, self.credentials)
class SlackBotService(PortMixin, Item): bot = reference(doc=""" An Item with a C{getFactory} method which returns a Twisted protocol factory. """, whenDeleted=reference.CASCADE) parent = inmemory(doc=""" A reference to the parent service of this service, whenever there is a parent. """) _service = inmemory(doc=""" A reference to the real endpoint L{IService}. """) def activate(self): self.parent = None def _makeService(self): """ Construct a service for the endpoint as described. """ factory = WebSocketClientFactory() factory.protocol = SlackProtocol factory.bot = self.bot return ClientService(self.bot, factory) def privilegedStartService(self): self._service = self._makeService() self._service.privilegedStartService() def startService(self): self._service = self._makeService() self._service.startService() def stopService(self): return self._service.stopService()
class StoredLaser(item.Item): """ A laser in storage. """ indirected = attributes.inmemory() damage = attributes.integer() def activate(self): """ Takes the laser out of storage. """ self.indirected = Laser(self.damage)
class BrokenCommittedItem(Item): """ Item class which changes database state in its committed method. Don't write items like this, they're broken. """ attribute = integer() _committed = inmemory() def committed(self): Item.committed(self) if getattr(self, '_committed', None) is not None: self._committed(self)
class POP3Listener(item.Item): implements(IProtocolFactoryFactory) powerupInterfaces = (IProtocolFactoryFactory, ) typeName = "quotient_pop3listener" schemaVersion = 3 # A cred portal, a Twisted TCP factory and as many as two # IListeningPorts portal = attributes.inmemory() factory = attributes.inmemory() certificateFile = attributes.bytes( "The name of a file on disk containing a private key and certificate " "for use by the POP3 server when negotiating TLS.", default=None) userbase = dependsOn(LoginSystem) # When enabled, toss all traffic into logfiles. debug = False def activate(self): self.portal = None self.factory = None # IProtocolFactoryFactory def getFactory(self): if self.factory is None: self.portal = portal.Portal(self.userbase, [self.userbase]) self.factory = POP3ServerFactory(self.portal) if self.debug: self.factory = policies.TrafficLoggingFactory( self.factory, 'pop3') return self.factory def setServiceParent(self, parent): """
class StatsService(item.Item, service.Service): """ Obsolete. Only present for schema compatibility. Do not use. """ installedOn = attributes.reference() parent = attributes.inmemory() running = attributes.inmemory() name = attributes.inmemory() statoscope = attributes.inmemory() queryStatoscope = attributes.inmemory() statTypes = attributes.inmemory() currentMinuteBucket = attributes.integer(default=0) currentQuarterHourBucket = attributes.integer(default=0) observers = attributes.inmemory() loginInterfaces = attributes.inmemory() userStats = attributes.inmemory() powerupInterfaces = (service.IService,)
class ContentResource(Item): """ Resource for accessing the content store. """ implements(IResource) powerupInterfaces = [IResource] addSlash = inmemory() contentStore = dependsOn(ContentStore) def getObject(self, name): def _notFound(f): f.trap(NonexistentObject) return None return self.contentStore.getSiblingObject(name).addErrback(_notFound) def childFactory(self, name): """ Hook up children. / is the root, nothing to see her. /new is how new objects are stored. /<objectId> is where existing objects are retrieved. """ if name == '': return self elif name == 'new': return ObjectCreator(self.contentStore) else: return self.getObject(name) return None # IResource def renderHTTP(self, ctx): """ Nothing to see here. """ return 'Entropy' def locateChild(self, ctx, segments): """ Dispatch to L{childFactory}. """ if len(segments) >= 1: res = self.childFactory(segments[0]) if res is not None: return res, segments[1:] return NotFound
class FakeMessageSource(item.Item): """ Stand-in for an item type returned from L{axiom.batch.processor}. Doesn't actually act as a source of anything, just used to test that items are kept track of properly. """ anAttribute = attributes.text(doc=""" Nothing. Axiom requires at least one attribute per item-type. """) added = attributes.inmemory() removed = attributes.inmemory() def activate(self): self.added = [] self.removed = [] def addReliableListener(self, what, style): self.added.append((what, style)) def removeReliableListener(self, what): self.removed.append(what)
class TransactedMethodItem(item.Item): """ Helper class for testing the L{axiom.item.transacted} decorator. """ value = text() calledWith = inmemory() def method(self, a, b, c): self.value = u"changed" self.calledWith = [a, b, c] raise Exception("TransactedMethodItem.method test exception") method.attribute = 'value' method = item.transacted(method)
class ClientEndpoint(_Endpoint, item.Item): """ A persisted client endpoint. """ description = attributes.bytes(allowNone=False) _cachedEndpoint = attributes.inmemory() factory = staticmethod(endpoints.clientFromString) def connect(self, factory): """ Connects the factory to the persisted endpoint. """ return self.instantiate().connect(factory)
class ServerEndpoint(item.Item, _Endpoint): """ A persisted server endpoint. """ description = attributes.bytes(allowNone=False) _cachedEndpoint = attributes.inmemory() factory = staticmethod(endpoints.serverFromString) def listen(self, factory): """ Listens with the factory on the connected endpoint. """ return self.instantiate().listen(factory)
class IndexableThing(item.Item): implements(ixmantissa.IFulltextIndexable) _uniqueIdentifier = attributes.bytes() _textParts = attributes.inmemory() _keywordParts = attributes.inmemory() _documentType = attributes.inmemory() def uniqueIdentifier(self): return self._uniqueIdentifier def textParts(self): return self._textParts def keywordParts(self): return self._keywordParts def documentType(self): return self._documentType def sortKey(self): return self.uniqueIdentifier()
class WorkListener(item.Item): comply = attributes.integer(doc=""" This exists solely to satisfy the requirement that Items have at least one persistent attribute. """) listener = attributes.inmemory(doc=""" A callable which will be invoked by processItem. This will be provided by the test method and will assert that the appropriate items are received, in the appropriate order. """) def processItem(self, item): self.listener(item)
class TestItem(item.Item): schemaVersion = 1 typeName = 'TestItem' foo = attributes.integer(indexed=True, default=10) bar = attributes.text() baz = attributes.timestamp() other = attributes.reference() booleanT = attributes.boolean() booleanF = attributes.boolean() activated = attributes.inmemory() checkactive = attributes.inmemory() checked = attributes.inmemory() myStore = attributes.reference() attributes.compoundIndex(bar, baz) def activate(self): self.activated = True if getattr(self, 'checkactive', False): assert isinstance(self.other, TestItem), repr(self.other) assert self.other != self, repr(self.other) self.checked = True
class TracebackCollector(Item, Service): implements(IService) typeName = 'mantissa_traceback_collector' schemaVersion = 1 tracebackCount = integer(default=0) parent = inmemory() running = inmemory() name = inmemory() powerupInterfaces = (IService,) def installed(self): self.setServiceParent(self.store) def startService(self): log.addObserver(self.emit) def stopService(self): log.removeObserver(self.emit) def emit(self, event): if event.get('isError') and event.get('failure') is not None: f = event['failure'] def txn(): self.tracebackCount += 1 Traceback(store=self.store, collector=self, failure=f) self.store.transact(txn) def getTracebacks(self): """ Return an iterable of Tracebacks that have been collected. """ return self.store.query(Traceback, Traceback.collector == self)
class Sword(ActivateHelper, Item): typeName = 'test_app_sword' schemaVersion = 3 name = text() damagePerHit = integer() activated = inmemory() def owner(): def get(self): return self.store.findUnique(InventoryEntry, InventoryEntry.owned == self).owner return get, owner = property(*owner())
class CachingItem(item.Item): """ An item that can do an expensive computation. It remembers how many times it has executed that computation, and caches its result. """ calls = attributes.integer(default=0) _cachedValue = attributes.inmemory() @caching.cached("_cachedValue") def expensiveComputation(self): """ A very expensive computation. """ self.calls += 1 return 1
####### DOUBLE-LEGACY UPGRADE SPECTACULAR !! ########### # declare legacy class. from axiom.item import declareLegacyItem declareLegacyItem(typeName="test_app_player", schemaVersion=2, attributes=dict(name=text(allowNone=True))) registerAttributeCopyingUpgrader(Adventurer, 2, 3) declareLegacyItem( typeName="test_app_sword", schemaVersion=2, attributes=dict(name=text(), damagePerHit=integer(), owner=reference(), activated=inmemory()), ) def upgradePlayerAndSword(oldplayer): newplayer = oldplayer.upgradeVersion("test_app_player", 1, 2) newplayer.name = oldplayer.name oldsword = oldplayer.sword newsword = oldsword.upgradeVersion( "test_app_sword", 1, 2, name=oldsword.name, damagePerHit=oldsword.hurtfulness * 2, owner=newplayer ) return newplayer, newsword
def listen(self): if self._listen is not None: _listen = self._listen else: from twisted.internet import reactor _listen = reactor.listenTCP return _listen(self.portNumber, self.factory.getFactory(), interface=self.interface.encode('ascii')) declareLegacyItem( typeName=normalize(qual(TCPPort)), schemaVersion=1, attributes=dict( portNumber=integer(), factory=reference(), parent=inmemory(), _listen=inmemory(), listeningPort=inmemory())) registerAttributeCopyingUpgrader(TCPPort, 1, 2) class SSLPort(PortMixin, Item): """ An Axiom Service Item which will bind a TCP port to a protocol factory when it is started. """ schemaVersion = 2 portNumber = integer(doc="""
registerUpgrader(sword2to3, 'test_app_sword', 2, 3) ####### DOUBLE-LEGACY UPGRADE SPECTACULAR !! ########### # declare legacy class. from axiom.item import declareLegacyItem declareLegacyItem(typeName = 'test_app_sword', schemaVersion = 2, attributes = dict(name=text(), damagePerHit=integer(), owner=reference(), activated=inmemory())) def upgradePlayerAndSword(oldplayer): newplayer = oldplayer.upgradeVersion('test_app_player', 1, 2) newplayer.name = oldplayer.name oldsword = oldplayer.sword newsword = oldsword.upgradeVersion('test_app_sword', 1, 3, name=oldsword.name, damagePerHit=oldsword.hurtfulness * 2) invent = InventoryEntry(store=newsword.store, owner=newplayer, owned=newsword) return newplayer, newsword