Posted by psichron on Thu 3 Jul 00:55
report abuse | download | new post
- # Import all the stuff that is needed
- from nevow import athena, loaders, tags as T, inevow
- from nevow import appserver, rend
- from twisted.python import filepath
- from twisted.application import service, internet
- from twisted.internet import reactor
- class AlertElement(athena.LiveElement):
- '''
- This is the class that will control the behaviour of the Alert element (essentially the table that rows gets added to)
- '''
- # Set LiveElement properties, these two are required:
- jsClass = u'MyModule.MyWidget' # Define jsClass, the name of the javascript module we're going to use. This links the javascript with the python source
- docFactory = loaders.xmlfile('tabletemplate.html') # Docfactory is what is returned to the client's browser
- def __init__(self, eventHandler, *a, **kw):
- super(AlertElement, self).__init__(*a, **kw) # Required.
- eventHandler.addSubscriber(self) # Subcribe this element to the eventHandler so it can be notified of new events.
- def fireEvent(self, eventID):
- '''
- fireEvent is called by the event handler when a new event is created by an EventCreator object. See EventHandler class.
- '''
- self.callRemote('addRow', unicode(eventID))
- class AlertPage(athena.LivePage):
- '''
- This is the /alerts page. Note that it is an athena LivePage.
- '''
- # LivePage property, required. This is what gets returned to the client's browser,
- # notice that alertElement gets included on this page.
- docFactory = loaders.stan(T.html[
- T.head(render=T.directive('liveglue')), #Required.
- T.body(render=T.directive('alertElement'))]) #An Alert Element(table thing) gets included on the /alerts page.
- def __init__(self, eventHandler, *a, **kw):
- super(AlertPage, self).__init__(*a,**kw) # Required
- self.eventHandler = eventHandler # Save the event handler we're using so we can subscribe the alert element to it.
- # Required, just tells Nevow where to look for our javascript module source.
- here = filepath.FilePath(__file__).parent().child('mymodule.js')
- self.jsModules.mapping.update({ # Still part of that.
- 'MyModule': here.path})
- # Tells Nevow how to render the 'alertElement' that we specified in docFactory,
- # ie, just create a new AlertElement object, set its parent and return it.
- def render_alertElement(self, ctx, data):
- f = AlertElement(self.eventHandler)
- f.setFragmentParent(self)
- return ctx.tag[f]
- class CreateEvent(rend.Page):
- '''
- This class creates an event and notifies the event handler when the page /event/<event ID> is visited..
- '''
- # As always, required. This is what is sent to the client's web browser.
- docFactory = loaders.stan (
- T.html [ T.head [T.title["Event Created"]],
- T.body [ render_body ]
- ])
- def __init__(self,eventHandler):
- self.eventHandler = eventHandler # Store the event handler that's being used.
- def render_body ( self, ctx, data ):
- request = inevow.IRequest ( ctx )
- eventID = request.prepath [ 1 ] # Get the event ID (ie, the part after /event/)
- self.eventHandler.fireEvent(eventID) # Tell the eventHandler about it.
- return "Event Created with ID: %s" % (eventID,)
- class CreateEventPage(rend.Page):
- '''
- This is /event.
- '''
- #Nevow property, this gets sent to the client's web browser.
- docFactory = loaders.stan(T.html[
- T.head(title = "Create an Event"),
- T.body[ T.h2["Create an Event by visiting /event/<ID of event to be created>"]]
- ])
- def __init__(self, eventHandler):
- self.eventHandler = eventHandler
- # "locateChild" is a catch-all that will handle any child page of /event/ , e.g. /event/lolpage, /event/foo
- def locateChild ( self, ctx, segments ):
- return ( CreateEvent(self.eventHandler), () ) # Create an event with the name of the child.
- class RootPage(rend.Page):
- '''
- This is the root page. What more explaining do you need?
- '''
- # Nevow properties:
- addSlash = True # Add a slash after the url.
- # Every page or element has a docFactory. This is what gets sent to the client's web browser.
- # It might look funny, but if you look closely you will see the way it is structured
- # is very much like html, ie <html><head><title>Root Page</title></head><body>...</body>.
- # And that is exactly what loaders.stan generates.
- docFactory = loaders.stan(T.html[
- T.head[T.title["Root Page"]],
- T.body[ T.h1["Index"],
- T.h2 [T.a ( href = 'alerts' ) [ "Alerts Page" ]],
- T.h2 [T.a ( href = 'event' ) [ "Generate an event"]]
- ]])
- def __init__ ( self, *args, **kwargs ):
- rend.Page.__init__ ( self, *args, **kwargs )
- self.eventHandler = EventHandler() # Create the event handler we're going to use.
- # This is what is returned when you try to access /alerts
- def child_alerts ( self, ctx ):
- return AlertPage(self.eventHandler)
- # This is what is returned when you try to access /event
- def child_event ( self, ctx ):
- return CreateEventPage(self.eventHandler)
- class EventHandler():
- '''
- The event handler class holds a list of subscribers, and notifies all of them if fireEvent is called.
- This class should be straight forward.
- '''
- def __init__(self):
- self.subscriberList = []
- def addSubscriber(self, subscriber):
- self.subscriberList.append(subscriber)
- def fireEvent(self, eventID):
- for subscriber in self.subscriberList:
- subscriber.fireEvent(eventID)
- # Mandatory boilerplate stuff to start up the server. Should be self explanatory.
- site = appserver.NevowSite(RootPage())
- application = service.Application("Copied from Athena Demo")
- webService = internet.TCPServer(8080, site)
- webService.setServiceParent(application)
Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.