[Twisted-web] Message Board Example

john janecek twisted-web@twistedmatrix.com
Tue, 20 Jan 2004 07:00:01 +0000 (UTC)


"""
this is the twisted message board made by John Janecek
me webpage is at http://www.jjanecek.ca.tf/ so you
can flame me and tell me what a piece of crap this code is :)
it basically was created so I can test out the leo editor
and also so I can see how nevow works

Lots of things that need to be done, like adding persistence so
messages are saved when stopping and starting server etc.

Anyway it is just a proof of concept, if anyway one finds it useful we
heya
"""
#messageboard for the twisted python server
from nevow import renderer
from nevow import tags
from nevow import formless
from nevow import freeform
from nevow.renderer import DynamicRenderer
import string
from time import gmtime, strftime

class TMessage(object) :
	def __init__(self,UserName,EMail,Subject,Message) :
		self.UserName=UserName
		self.EMail=EMail
		self.Subject=Subject
		self.Message=Message
		self.DateTime=strftime("%a, %d %b %Y %H:%M:%S", gmtime())
		self.Messages=[]
	def getMessages(self) :
		return self.Messages
		
	"""
	If index=[] message is just appended to the end
	"""
	def addMessage(self,Message,Index=[]) :
		if Index==[] :
			self.Messages.append(Message)
		else :
			Parent=self.getMessage(Index)
			Parent.addMessage(Message)
	def getMessage(self,Index) :	
		if isinstance(Index,list) :
			if(len(Index)==1) :
				return self.Messages[Index[0]]
			else :
				Current=Index.pop(0)
				return self.Messages[Current].getMessage(Index)
				
		else :
			return self.Messages[Index]
	
class TMessageBoard(object) :
	"""
	Message board which will implement the posting and recieving of messages.
	This part of the board handles the actual nuts and bolts of the Message Board
including storage of Messages
	
	Probably Could Have Inherited off TMessage
	"""
	def __init__(self) :
		self.Messages=[]
	"""
	returns all the messages on the board
	"""
	def getMessages(self) :
		return self.Messages
	"""
	If index=[] message is just appended to the end
	"""
	
	def addMessage(self,Message,Index=[]) :
		if Index==[] :
			self.Messages.append(Message)
		else :
			Parent=self.getMessage(Index)
			Parent.addMessage(Message)
	def getMessage(self,Index) :	
		if isinstance(Index,list) :
			if(len(Index)==1) :
				return self.Messages[Index[0]]
			else :
				Current=Index.pop(0)
				return self.Messages[Current].getMessage(Index)
				
		else :
			return self.Messages[Index]
class IMessageForm(formless.TypedInterface) :
	
	def MessagePost(self,UserName=formless.String(),
					EMail=formless.String(),
					Subject=formless.String(),
					Message=formless.Text(),
					) :
		pass
		
	MessagePost = formless.autocallable(MessagePost,action="Post Message")
class MessagePage(renderer.Renderer) :
	__implements__ = IMessageForm,renderer.Renderer.__implements__
	def __init__(self,MessageBoard) :
		renderer.Renderer.__init__(self)
		self.MessageBoard=MessageBoard
		self.CurrentMessageIndex=[]
		
	def beforeRender(self, request):
		#print "request ",request.args
		if request.args.has_key("messageid") :
			self.CurrentMessageIndex=string.split(request.args["messageid"][0])
			self.CurrentMessageIndex=map(int,self.CurrentMessageIndex)
		else :
			self.CurrentMessageIndex=[]
		print "Current Message ",self.CurrentMessageIndex
	"""
	Method to Serialize messages
	"""
	def SerializeMessage(self,Message) :
		Row1=tags.tr()[
				tags.td["Subject :"],
				tags.td[Message.Subject],
				tags.td[Message.DateTime]
				]
		Row2=tags.tr[
			tags.td[Message.Message]
			]
		return tags.table(border="1")[Row1,Row2]
	def currentMessage(self,context, data) :
		try :
			return
self.SerializeMessage(self.MessageBoard.getMessage(self.CurrentMessageIndex))
		except Exception,Msg:
			self.CurrentMessageIndex=[]
			print "Error ",Msg
			return ""
	def SerializeMessageHeader(self,Messages,IndexDepth=[]) :
		MessageList=[]
		
		IndexStr="".join(map(lambda x : str(x)+" ",IndexDepth))
		IndexStr="?messageid="+IndexStr+" "
		Index=len(Messages)-1
		#done to display newest messages first
		
		for Message in Messages[::-1] :
			IndexDepth.append(Index)
			if IndexDepth==self.CurrentMessageIndex :
				MessageLine=tags.li[
					tags.span(_class="selected")[
						Message.UserName,
						tags.a(href=IndexStr+str(Index))[Message.Subject],
						Message.DateTime
						]
					]
				MessageList.append(MessageLine)
			else :
				MessageLine=tags.li[
					tags.span(_class="notselected")[
						Message.UserName,
						tags.a(href=IndexStr+str(Index))[Message.Subject],
						Message.DateTime
						]
					]
				MessageList.append(MessageLine)
			
			ChildMessages=Message.getMessages()
			MessageList.append(self.SerializeMessageHeader(ChildMessages))
			IndexDepth.pop()
			Index-=1
			
		return tags.ul[MessageList]
	def showMessages(self,context,data) :
		Messages=self.MessageBoard.getMessages()
		return self.SerializeMessageHeader(Messages)
		
	document = tags.html[
			tags.head[
				tags.title["Twisted Message Board"],
				tags.link(href="/freeform_css",type="text/css", rel="stylesheet")
				],
			tags.body[
				"Message Board Post Page",
				tags.a(href="./")["Post New Thread"],
				tags.p[ showMessages ],
				tags.p[ currentMessage ],
				tags.p[ freeform.configure ]
				]
		]
	def MessagePost(self,UserName,EMail,Subject,Message) :
		Message=TMessage(UserName,EMail,Subject,Message)
		self.MessageBoard.addMessage(Message,self.CurrentMessageIndex)
	def getDynamicChild(self,name,request) :
		print "request ",request.args
		return self
	def child_freeform_css(self,request) :
		Style="""
		.selected {
		color: #FF0000;
		background-color: #003399;
		}
		.notselected{
		color: #0000FF;
		background-color: #000000;
		}
		
		.freeform-typed { clear: both; }
		.freeform-property-binding { clear: both; border: 1px solid blue; padding:
0.5em; width: auto }
		.freeform-method-binding { clear: both; border: 1px solid black; padding:
0.5em; width: auto }
		.freeform-argument-binding { clear: both; border: 1px solid blue; padding:
0.5em; width: auto }
		.freeform-binding-content { border-top: 1px dashed #bdedfe; margin-top: 0.5em;
padding-top: 0.5em }
		.freeform-label { float: left; width: 200px; }
		.freeform-input { float: left; width: 200px; }
		.freeform-error { color: red; }
		.freeform-description { clear: both; border-bottom: 1px dashed #bdedfe;
margin-bottom: 0.5em; padding-bottom: 0.5em }
		.freeform-list-item { clear: both; width: auto }
		.freeform-form-label { color: #666666 }
	
		.freeform-textarea { width: 5in; height: 3in }
	
		.freeform-success { padding: 0.5em; border: 1px dashed green; }
		.freeform-failure { padding: 0.5em; color: red; border: 1px dashed red; }
	
		.freeform-list { border: 1px dashed #cdcdcd; }
		.freeform-dictionary { border: 1px dashed #dedede; }
		.freeform-action-group { margin: 0px }
		.freeform-action { color: green }
		.freeform-action-selection { background-color: red; height: 1em; width: 1em; }
	
		.freeform-group-binding { border: 1px dashed #efabab }
		.freeform-grouped-property-binding {}
		.freeform-grouped-method-binding {}
		"""
		
		return DynamicRenderer(Style)

def CreateMessageBoard() :
	"""
	Creates a Message board so it can be run in a Server
	returns : returns a MessagePage Object
	"""
	MessageBoard=TMessageBoard()
	Page=MessagePage(MessageBoard)
	return Page

#the tap file

import sys
import os
#print "current dir ",os.getcwd()
#not really sure why i need to fix this
sys.path.append(os.getcwd())
from twisted.application import service
from twisted.application import internet
from nevow import appserver
import msg_board

application = service.Application("MessageBoard")

WebServer=internet.TCPServer(
    8080, 
    appserver.NevowSite(
        msg_board.CreateMessageBoard()
    )
)
WebServer.setServiceParent(application)

#from twisted.internet import defer

#def Stopped() :
#	d=defer.Deferred()
#	print "WebServer Stopped"

#WebServer.stopService=Stopped
#print "WebServer Deferred ",Defered