diff --git a/LDP/lampadas/lampadas/Makefile b/LDP/lampadas/lampadas/Makefile index 2ce287ce..065e7e34 100644 --- a/LDP/lampadas/lampadas/Makefile +++ b/LDP/lampadas/lampadas/Makefile @@ -9,5 +9,6 @@ start: tap clean: rm -f *.pyc rm -f *.tap + rm -f *.log diff --git a/LDP/lampadas/lampadas/home.py b/LDP/lampadas/lampadas/home.py new file mode 100644 index 00000000..18bdc5d0 --- /dev/null +++ b/LDP/lampadas/lampadas/home.py @@ -0,0 +1,77 @@ +#!/usr/bin/python + +from twisted.web.woven import model, view, controller +from twisted.web.woven import widgets, input +from twisted.web import domhelpers + +#from TwistedQuotes import quoters + + +import cgi + +class MQuote(model.WModel): + def __init__(self): + print 'Loading MQuote' + model.WModel.__init__(self) + #self._filename = filename + #self._quoter = quoters.FortuneQuoter([filename]) + self.quote = "Hello, world!" + self.title = "Quotes Galore!" + self.newQuote = "" + + def updateQuote(self): + self.quote = 'Hello, world!' + +class QuoteWidget(widgets.Widget): + def setUp(self, request, node, data): + """ + Set up this Widget object before it gets rendered into HTML. + + Since self is a Widget, I can use the higher level widget API to add a + Text widget to self. I then rely on Widget.generateDOM to convert + from Widgets into the Document Object Model. + """ + self.add(widgets.Text(cgi.escape(data))) + + +class VQuote(view.WView): + templateFile = "home.xhtml" + + def setUp(self, request, document): + """ + Set things up for this request. + """ + self.model.updateQuote() + + def wvfactory_quote(self, request, node, model): + """Create a widget which knows how to render my model's quote.""" + domhelpers.clearNode(node) + return QuoteWidget(model) + + def wvfactory_title(self, request, node, model): + """Create a widget which knows how to render my model's title.""" + domhelpers.clearNode(node) + return widgets.Text(model) + + +class NewQuoteHandler(input.SingleValue): + def check(self, request, data): + if data: + return 1 + + def commit(self, request, node, newQuote): + print "committing new quote", `newQuote` + file = open(self.model.getQuoteFilename(), 'a') + file.write('\n%\n' + newQuote) + + +class CQuote(controller.WController): + def wcfactory_newQuote(self, model): + """Create a handler which knows how to verify input in a form with the + name "newQuote".""" + return NewQuoteHandler(model) + + +view.registerViewForModel(VQuote, MQuote) +controller.registerControllerForModel(CQuote, MQuote) + diff --git a/LDP/lampadas/lampadas/home.rpy b/LDP/lampadas/lampadas/home.rpy new file mode 100644 index 00000000..8a74244b --- /dev/null +++ b/LDP/lampadas/lampadas/home.rpy @@ -0,0 +1,22 @@ +#!/usr/bin/python + +# -*- Python -*- + +import home + +#__file__ is defined to be the name of this file; this is to +#get the sibling file "quotes.txt" which should be in the same directory +import os +#quotefile = os.path.join(os.path.split(__file__)[0], "quotes.txt") + +# Construct a model object which will contain the data for display by the +# web page +model = home.MQuote() + +# ResourceScript requires us to define 'resource'. This resource is used +# to render the page. +resource = home.CQuote(model) + +# The CQuote controller will look up a View (VQuote) and call render() +# on it, rendering the DOMTemplate + diff --git a/LDP/lampadas/lampadas/home.xhtml b/LDP/lampadas/lampadas/home.xhtml new file mode 100644 index 00000000..71317257 --- /dev/null +++ b/LDP/lampadas/lampadas/home.xhtml @@ -0,0 +1,28 @@ + + + + Title will go here + + + + + + +

+ Title will go here +

+ +
+			Quote will go here.
+		
+ +
+ + +
+ Refresh + + + diff --git a/LDP/lampadas/lampadas/object_server.py b/LDP/lampadas/lampadas/object_server.py deleted file mode 100644 index 993e8980..00000000 --- a/LDP/lampadas/lampadas/object_server.py +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/python - -from Config import config - -from twisted.spread import pb -from twisted.internet import defer -from twisted.enterprise import adbapi, row, reflector -from twisted.enterprise.sqlreflector import SQLReflector - -class BlockRow(row.RowObject, pb.Referenceable): - rowColumns = [('block_code', 'varchar'), - ('block', 'varchar'), - ('created', 'timestamp'), - ('updated', 'timestamp')] - rowKeyColumns = [('block_code', 'varchar')] - rowTableName = 'block' - -def connected(result): - print 'Done initializing. Message: ', result - -def success(object): - print 'ObjectService loaded: ', object - return object - -class ObjectPerspective(pb.Perspective): - - def __init__(self, perspectiveName, identityName='Nobody'): - pb.Perspective.__init__(self, perspectiveName, identityName) - if config.db_type=='pgsql': - db_module = 'pyPgSQL.PgSQL' - else: - db_module = 'pyMySQL.MySQL' - dbpool = adbapi.ConnectionPool(db_module, database=config.db_name, user='www-data') - self.reflector = SQLReflector(dbpool, [BlockRow], connected) - - def perspective_get_block_by_code(self, code): - print 'ObjectService serving block: ', code - w = [('block_code', reflector.EQUAL, code)] - self.reflector.loadObjectsFrom('block', whereClause=w).addCallback(success) - -class ObjectService(pb.Service): - perspectiveClass = ObjectPerspective - - diff --git a/LDP/lampadas/lampadas/objects.py b/LDP/lampadas/lampadas/objects.py new file mode 100755 index 00000000..b5d291e1 --- /dev/null +++ b/LDP/lampadas/lampadas/objects.py @@ -0,0 +1,42 @@ +#!/usr/bin/python + +# Lampadas imports +from Config import config + +# Twisted imports +from twisted.internet import reactor +from twisted.enterprise import adbapi, row, reflector +from twisted.enterprise.sqlreflector import SQLReflector +from twisted.python import usage +from twisted.cred.authorizer import DefaultAuthorizer +from twisted.internet import defer + +# Sibling imports +from row import BlockRow, PageRow, PageI18nRow + +ROW_CLASSES = [BlockRow, PageRow, PageI18nRow] + +class Page: + def __init__(self, refl): + self.refl = refl + + def get_all(self, callback): + print 'Page.get_all()' + self.refl.loadObjectsFrom('page').addCallback(callback) + + def get_by_code(self, code, callback): + print 'Page.get_by_code(%s): ' % code + w = [('block_code', reflector.EQUAL, code)] + self.refl.loadObjectsFrom('block', whereClause=w).addCallback(callback) + +class Objects: + def connect(self, callback): + if config.db_type=='pgsql': + db_module = 'pyPgSQL.PgSQL' + else: + db_module = 'pyMySQL.MySQL' + self.dbpool = adbapi.ConnectionPool(db_module, database=config.db_name, user='www-data') + self.refl = SQLReflector(self.dbpool, ROW_CLASSES, callback) + self.page = Page(self.refl) + +object_server = Objects() diff --git a/LDP/lampadas/lampadas/pbobjects.py b/LDP/lampadas/lampadas/pbobjects.py new file mode 100755 index 00000000..c13f248b --- /dev/null +++ b/LDP/lampadas/lampadas/pbobjects.py @@ -0,0 +1,80 @@ +#!/usr/bin/python + +# Lampadas imports +from Config import config + +# Twisted imports +from twisted.spread import pb +from twisted.internet import reactor +from twisted.enterprise import adbapi, row, reflector +from twisted.enterprise.sqlreflector import SQLReflector +from twisted.python import usage +from twisted.cred.authorizer import DefaultAuthorizer +from twisted.internet import defer + +# Sibling imports +from row import BlockRow, PageRow, PageI18nRow + +ROW_CLASSES = [BlockRow, PageRow, PageI18nRow] + +def loaded(object): + print 'ObjectService loaded: ', object + return object + +class Page(pb.Copyable): + def __init__(self, refl): + print 'Initializing Page' + refl.loadObjectsFrom('page').addCallback(self.loaded) + + def loaded(self, pages): + print 'Page.loaded()' + self.pages = pages + + def get_all(self, refl): + refl.loadObjectsFrom('page').addCallback(loaded) + + def get_by_code(self, refl, code): + print 'ObjectService serving block: ', code + w = [('block_code', reflector.EQUAL, code)] + refl.loadObjectsFrom('block', whereClause=w).addCallback(loaded) + +def connected(result): + print 'Object Server Ready.' + +class Objects(pb.Perspective): + + def __init__(self, perspectiveName, identityName='Nobody'): + pb.Perspective.__init__(self, perspectiveName, identityName) + if config.db_type=='pgsql': + self.db_module = 'pyPgSQL.PgSQL' + else: + self.db_module = 'pyMySQL.MySQL' + self.dbpool = adbapi.ConnectionPool(self.db_module, database=config.db_name, user='www-data') + self.refl = SQLReflector(self.dbpool, ROW_CLASSES, connected) + reactor.callLater(0.5, self.load) + + def load(self): + print 'Objects.load()' + self.page = Page(self.refl) + + def perspective_page(self): + print 'Client requested pages' + return self.page.pages + +class ObjectService(pb.Service): + perspectiveClass = Objects + + +class Options(usage.Options): + optParameters = [['port', 'p', 8790, 'Port to listed on.']] + +def updateApplication(app, config): + port = config['port'] + if port: + auth = DefaultAuthorizer(app) + serv = ObjectService('lampadas.objects', app, auth) + serv.createPerspective("guest").makeIdentity("guest") + fact = pb.BrokerFactory(pb.AuthRoot(auth)) + app.listenTCP(int(port), fact) + reactor.run() + diff --git a/LDP/lampadas/lampadas/pbtap.py b/LDP/lampadas/lampadas/pbtap.py index 3f4c7871..64bcb791 100644 --- a/LDP/lampadas/lampadas/pbtap.py +++ b/LDP/lampadas/lampadas/pbtap.py @@ -6,7 +6,7 @@ from twisted.spread import pb from twisted.cred.authorizer import DefaultAuthorizer class Options(usage.Options): - optParameters = [["port", "o", 8790, + optParameters = [["port", "p", 8790, "Port to listen with ObjectService"]] def updateApplication(app, config): diff --git a/LDP/lampadas/lampadas/plugins.tml b/LDP/lampadas/lampadas/plugins.tml index d2ae2afb..7cfbeb3b 100644 --- a/LDP/lampadas/lampadas/plugins.tml +++ b/LDP/lampadas/lampadas/plugins.tml @@ -3,3 +3,15 @@ register("Lampadas Object Broker", description="Lampadas Documentation Management object server.", type="tap", tapname="lampadas") + +register("Lampadas Website", + "lampadas.web", + description="Lampadas Website.", + type="tap", + tapname="lampadasweb") + +register("Lampadas Data Objects", + "lampadas.pbobjects", + description="Lampadas Data Object Server.", + type="tap", + tapname="objects") diff --git a/LDP/lampadas/lampadas/row.py b/LDP/lampadas/lampadas/row.py new file mode 100644 index 00000000..8754b763 --- /dev/null +++ b/LDP/lampadas/lampadas/row.py @@ -0,0 +1,38 @@ +#!/usr/bin/python + +from twisted.enterprise import row + +class BlockRow(row.RowObject): + rowColumns = [('block_code', 'varchar'), + ('block', 'varchar'), + ('created', 'timestamp'), + ('updated', 'timestamp')] + rowKeyColumns = [('block_code', 'varchar')] + rowTableName = 'block' + +class PageRow(row.RowObject): + rowColumns = [('page_code', 'varchar'), + ('section_code', 'varchar'), + ('sort_order', 'int'), + ('template_code', 'varchar'), + ('data', 'varchar'), + ('only_dynamic', 'bool'), + ('only_registered', 'bool'), + ('only_admin', 'bool'), + ('only_sysadmin', 'bool')] + rowKeyColumns = [('page_code', 'varchar')] + rowTableName = 'page' + +class PageI18nRow(row.RowObject): + rowColumns = [('page_code', 'varchar'), + ('lang', 'varchar'), + ('title', 'text'), + ('menu_name', 'text'), + ('page', 'text'), + ('version', 'varchar'), + ('created', 'timestamp'), + ('updated', 'timestamp')] + rowKeyColumns = [('page_code', 'varchar'), + ('lang', 'varchar')] + rowTableName = 'page_i18n' + diff --git a/LDP/lampadas/lampadas/test.py b/LDP/lampadas/lampadas/test.py index 00e7662a..9febb4ae 100755 --- a/LDP/lampadas/lampadas/test.py +++ b/LDP/lampadas/lampadas/test.py @@ -12,7 +12,8 @@ from twisted.spread import pb def connected(perspective): print 'Connected.' - perspective.callRemote('get_block_by_code', code='blkheader').addCallbacks(success, failure) + perspective.callRemote('load').addCallbacks(success, failure) + perspective.callRemote('page').addCallbacks(success, failure) def connect_failure(error): print "Error connecting to ObjectService.." @@ -26,6 +27,13 @@ def failure(error): print "Failed to obtain a block from the ObjectService." reactor.stop() +def gotRoot(root): + print 'Got root: ', root + print dir(root) + +def gotNoRoot(error): + print 'Failed to obtain root: ', error + pb.connect("localhost", # host name 8790, # port number "guest", # identity name @@ -36,4 +44,5 @@ pb.connect("localhost", # host name ).addCallbacks(connected, # what to do when we get connected connect_failure) # and what to do when we can't +pb.getObjectAt('localhost', 8790, 30).addCallbacks(gotRoot, gotNoRoot) reactor.run() # start the main loop diff --git a/LDP/lampadas/lampadas/web.py b/LDP/lampadas/lampadas/web.py new file mode 100644 index 00000000..5596f52a --- /dev/null +++ b/LDP/lampadas/lampadas/web.py @@ -0,0 +1,54 @@ +#!/usr/bin/python + +from twisted.internet import app +from twisted.web import server, widgets +from twisted.python import usage +from twisted.web.resource import Resource +from twisted.internet import reactor +from objects import object_server + +class Options(usage.Options): + optParameters = [["port", "p", 8080, + "Port to listen with Webserver"]] + +class Page(widgets.WidgetPage): + template = '%%%%self.widget%%%%' + +class Gadget(widgets.Gadget): + def __init__(self): + print 'Initializing gadget' + widgets.Gadget.__init__(self) + self.pageFactory = Page + self.putWidget('hello', HelloWorld()) + self.putWidget('', HelloWorld()) + print 'connecting object_server...' + object_server.connect(self.connected) + + def connected(self, message): + print 'object server is connected, loading pages...' + object_server.page.get_all(self.loaded) + + def loaded(self, pages): + print 'Pages loaded:' + self.pages = pages + for row in self.pages: + page = WebPage() + page.row = row + self.putWidget(page.row.page_code, page) + +class WebPage(widgets.Widget): + def display(self, request): + return [self.row.page_code] + +class HelloWorld(widgets.Widget): + def display(self, request): + return ['Hello, world!'] + +def updateApplication(app, config): + port = config['port'] + root = Gadget() + site = server.Site(root) + app.listenTCP(port, site) + +root = Gadget() +site = server.Site(root)