# HG changeset patch # User Goffi # Date 1301009578 -3600 # Node ID c28a4840e1a8fbf82b4b154afebfc153d39c847f # Parent c80b75bf2e91fc463547c564e4a2554eb15ed357 server: microblog resource diff -r c80b75bf2e91 -r c28a4840e1a8 libervia.tac --- a/libervia.tac Fri Mar 25 00:31:27 2011 +0100 +++ b/libervia.tac Fri Mar 25 00:32:58 2011 +0100 @@ -28,10 +28,13 @@ from twisted.web import error as weberror from twisted.web.static import File from twisted.web.resource import Resource +from twisted.words.protocols.jabber.jid import JID from txjsonrpc.web import jsonrpc from txjsonrpc import jsonrpclib from sat_frontends.bridge.DBus import DBusBridgeFrontend,BridgeExceptionNoService +from server_side.blog import MicroBlog + TIMEOUT = 120 #Session's time out, after that the user will be disconnected @@ -237,17 +240,14 @@ self.request = request return jsonrpc.JSONRPC.render(self, request) + class Libervia(service.Service): def __init__(self): root = File("output/") self.signal_handler = SignalHandler(self) - root.putChild('json_signal_api', self.signal_handler) _register = Register(self) self.signal_handler.plugRegister(_register) - root.putChild('json_api', MethodHandler(self)) - root.putChild('register_api', _register) - self.site = server.Site(root) self.sessions = {} #key = session value = user ## bridge ## try: @@ -260,6 +260,12 @@ self.bridge.register("connectionError", self.signal_handler.connectionError) for signal_name in ['presenceUpdate', 'personalEvent']: self.bridge.register(signal_name, self.signal_handler.getGenericCb(signal_name)) + root.putChild('json_signal_api', self.signal_handler) + root.putChild('json_api', MethodHandler(self)) + root.putChild('register_api', _register) + root.putChild('blog', MicroBlog(self)) + root.putChild('css', File("server_css/")) + self.site = server.Site(root) def startService(self): reactor.listenTCP(8080, self.site) diff -r c80b75bf2e91 -r c28a4840e1a8 server_css/blog.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server_css/blog.css Fri Mar 25 00:32:58 2011 +0100 @@ -0,0 +1,53 @@ +/* +Libervia: a Salut à Toi frontend +Copyright (C) 2011 Jérôme Poisson (goffi@goffi.org) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + + +.mblog_title { + text-align: center; + font-size: x-large; + font-weight: bold; + margin-bottom: 40px; +} + +.mblog_content { + width: 60%; + text-align:center; + + border: 1px solid LightGray; + + border-bottom-width: 1px; + margin-left: auto; + margin-right: auto; + margin-bottom: 20px; + margin-top: 5px; + padding-left: 10px; + padding-right: 10px; + padding-top: 5px; + padding-bottom: 5px; + + -moz-border-radius: 15px; + -webkit-border-radius: 15px; + border-radius: 15px; +} + +.mblog_timestamp { + display: block; + font-size: small; + border-bottom: 1px dashed LightGrey; + color: gray; +} diff -r c80b75bf2e91 -r c28a4840e1a8 server_side/__init__.py diff -r c80b75bf2e91 -r c28a4840e1a8 server_side/blog.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server_side/blog.py Fri Mar 25 00:32:58 2011 +0100 @@ -0,0 +1,88 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +""" +Libervia: a Salut à Toi frontend +Copyright (C) 2011 Jérôme Poisson (goffi@goffi.org) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +""" + +from server_side.html_tools import sanitizeHtml +from twisted.internet import reactor, defer +from twisted.web import server +from twisted.web.resource import Resource +from twisted.words.protocols.jabber.jid import JID +from datetime import datetime + +class MicroBlog(Resource): + isLeaf = True + + ERROR_TEMPLATE = """ + + + MICROBLOG ERROR + + +

%s

+ + + """ + + def __init__(self,host): + self.host = host + Resource.__init__(self) + if not host.bridge.isConnected("libervia"): #FIXME: hard coded value for test + host.bridge.connect("libervia") + + def render_GET(self, request): + if not request.postpath: + return MicroBlog.ERROR_TEMPLATE % "You must indicate a nickname" + else: + prof_requested = request.postpath[0] + #TODO: char check: only use alphanumerical chars + some extra(_,-,...) here + prof_found = self.host.bridge.getProfileName(prof_requested) + if not prof_found or prof_found=='libervia': + return MicroBlog.ERROR_TEMPLATE % "Invalid nickname" + else: + pub_jid=JID(self.host.bridge.getParamA('JabberID','Connection','value',prof_found)) + d = defer.Deferred() + d.addCallbacks(self.render_html_blog, self.render_error_blog, [request, prof_found], None, [request, prof_found], None) + self.host.bridge.getLastMicroblogs(pub_jid.userhost(), 10, 'libervia', d.callback, d.errback) + + return server.NOT_DONE_YET + + def render_html_blog(self, mblog_data, request, profile): + user = sanitizeHtml(profile).encode('utf-8') + request.write(""" + + + + %(user)s's microblog + + +
%(user)s
+ """ % {'user':user}) + for entry in mblog_data: + timestamp = float(entry.get('timestamp',0)) + _datetime = datetime.fromtimestamp(timestamp) + request.write("
%(date)s%(content)s
" % { + 'date':_datetime, + 'content':sanitizeHtml(entry['content']).encode('utf-8')}) + request.write('') + request.finish() + + def render_error_blog(self, error, request): + request.write(MicroBlog.ERROR_TEMPLATE % "Can't access requested data") + request.finish()