From af42aae7cc7c993b21487ed505965ff36461d703 Mon Sep 17 00:00:00 2001 From: Dan Helfman Date: Mon, 17 Nov 2008 15:23:22 -0800 Subject: [PATCH] Converted the Luminotes blog to work like a forum, so now you can post comments on Luminotes blog posts. --- NEWS | 3 +++ controller/Forums.py | 22 ++++++++++++++++++-- controller/Root.py | 41 +++----------------------------------- controller/Users.py | 2 +- static/html/community.html | 2 +- view/Forum_page.py | 19 ++++++++++++------ view/Product_page.py | 2 +- 7 files changed, 42 insertions(+), 49 deletions(-) diff --git a/NEWS b/NEWS index 2c62f5a..044411f 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,9 @@ so that the note title links have a little more horizontal breathing room. * You can now add an existing note directly to the note tree, instead of having to click "options" -> "show on startup". + * Improved site navigation by adding more useful links to the page footer. + * Converted the Luminotes blog to work like a forum, so now you can post + comments on Luminotes blog posts. * Fixed a bug in which search result note summaries were not showing the portion of the note that matched the search term. (Luminotes Server) * Fixed a visual bug in which undoing the deletion of a note didn't always diff --git a/controller/Forums.py b/controller/Forums.py index 2cf9101..6c50bb9 100644 --- a/controller/Forums.py +++ b/controller/Forums.py @@ -1,3 +1,4 @@ +import os.path import cherrypy from model.User import User from model.Notebook import Notebook @@ -97,8 +98,9 @@ class Forum( object ): start = Valid_int( min = 0 ), count = Valid_int( min = 1, max = 50 ), user_id = Valid_id( none_okay = True ), + note_id = Valid_id( none_okay = True ), ) - def index( self, start = 0, count = 50, user_id = None ): + def index( self, start = 0, count = 50, note_id = None, user_id = None ): """ Provide the information necessary to display the current threads within a forum (in reverse chronological order). @@ -107,11 +109,16 @@ class Forum( object ): @param start: index of first forum thread to display (optional, defaults to 0) @type count: integer or NoneType @param count: how many forum threads to display (optional, defaults to quite a few) + @type note_id: unicode or NoneType + @param note_id: id of thread to redirect to (optional, legacy support for old URLs) @type user_id: unicode or NoneType @param user_id: id of the current user @rtype: unicode @return: rendered HTML page """ + if note_id: + return dict( redirect = os.path.join( cherrypy.request.path, note_id ) ) + result = self.__users.current( user_id ) parents = [ notebook for notebook in result[ u"notebooks" ] if notebook.trash_id and not notebook.deleted ] if len( parents ) > 0: @@ -123,12 +130,19 @@ class Forum( object ): if anonymous is None: raise Access_error() + # whether this is a blog determines whether the posts are diplayed in forward or reverse + # chronological order + if self.__name == u"blog": + reverse = False + else: + reverse = True + # load a slice of the list of the threads in this forum, excluding those with a default name threads = self.__database.select_many( Notebook, anonymous.sql_load_notebooks( parents_only = False, undeleted_only = True, tag_name = u"forum", tag_value = self.__name, - exclude_notebook_name = self.DEFAULT_THREAD_NAME, reverse = True, + exclude_notebook_name = self.DEFAULT_THREAD_NAME, reverse = reverse, start = start, count = count, ) ) @@ -220,6 +234,10 @@ class Forum( object ): if anonymous is None: raise Access_error() + # for now, crappy hard-coding to prevent just anyone from creating a blog thread + if self.__name == u"blog" and user.username != u"witten": + raise Access_error() + # create the new notebook thread thread_id = self.__database.next_id( Notebook, commit = False ) thread = Notebook.create( thread_id, self.DEFAULT_THREAD_NAME, user_id = user.object_id ) diff --git a/controller/Root.py b/controller/Root.py index e222d54..17fb080 100644 --- a/controller/Root.py +++ b/controller/Root.py @@ -7,7 +7,7 @@ from Notebooks import Notebooks from Users import Users, grab_user_id from Groups import Groups from Files import Files -from Forums import Forums +from Forums import Forums, Forum from Database import Valid_id, end_transaction from Users import update_auth from model.Note import Note @@ -59,6 +59,7 @@ class Root( object ): ) self.__notebooks = Notebooks( database, self.__users, self.__files, settings[ u"global" ].get( u"luminotes.https_url", u"" ) ) self.__forums = Forums( database, self.__notebooks, self.__users ) + self.__blog = Forum( database, self.__notebooks, self.__users, u"blog" ) self.__suppress_exceptions = suppress_exceptions # used for unit tests @expose( Main_page ) @@ -253,43 +254,6 @@ class Root( object ): def take_a_tour( self ): return dict( redirect = u"/tour" ) - @expose( view = Main_page, rss = Notebook_rss ) - @end_transaction - @grab_user_id - @validate( - start = Valid_int( min = 0 ), - count = Valid_int( min = 1, max = 50 ), - note_id = Valid_id( none_okay = True ), - user_id = Valid_id( none_okay = True ), - ) - def blog( self, start = 0, count = 5, note_id = None, user_id = None ): - """ - Provide the information necessary to display the blog notebook with notes in reverse - chronological order. - - @type start: unicode or NoneType - @param start: index of recent note to start with (defaults to 0, the most recent note) - @type count: int or NoneType - @param count: number of recent notes to display (defaults to 10 notes) - @type note_id: unicode or NoneType - @param note_id: id of single note to load (optional) - @rtype: unicode - @return: rendered HTML page - @raise Validation_error: one of the arguments is invalid - """ - result = self.__users.current( user_id ) - blog_notebooks = [ nb for nb in result[ "notebooks" ] if nb.name == u"Luminotes blog" ] - - result.update( self.__notebooks.recent_notes( blog_notebooks[ 0 ].object_id, start, count, user_id ) ) - - # if a single note was requested, just return that one note - if note_id: - result[ "notes" ] = [ note for note in result[ "notes" ] if note.object_id == note_id ] - - result[ "http_url" ] = self.__settings[ u"global" ].get( u"luminotes.http_url", u"" ) - - return result - @expose( view = Main_page ) @end_transaction @grab_user_id @@ -493,3 +457,4 @@ class Root( object ): groups = property( lambda self: self.__groups ) files = property( lambda self: self.__files ) forums = property( lambda self: self.__forums ) + blog = property( lambda self: self.__blog ) diff --git a/controller/Users.py b/controller/Users.py index 10de251..d5773f4 100644 --- a/controller/Users.py +++ b/controller/Users.py @@ -638,7 +638,7 @@ class Users( object ): anon_notebooks = self.__database.select_many( Notebook, anonymous.sql_load_notebooks( undeleted_only = True ) ) if user_id and user_id != anonymous.object_id: - notebooks = self.__database.select_many( Notebook, user.sql_load_notebooks() ) + notebooks = self.__database.select_many( Notebook, user.sql_load_notebooks( parents_only = True ) ) groups = self.__database.select_many( Group, user.sql_load_groups() ) # if the user is not logged in, return a login URL else: diff --git a/static/html/community.html b/static/html/community.html index d8fd298..ae4b48d 100644 --- a/static/html/community.html +++ b/static/html/community.html @@ -13,7 +13,7 @@ In the Luminotes discussion forums, you can ask about Luminotes features and chat with your fellow Luminoters.

-

blog

+

blog

With the Luminotes blog, you can stay up to date on all the latest features diff --git a/view/Forum_page.py b/view/Forum_page.py index 5bfaf15..954cd67 100644 --- a/view/Forum_page.py +++ b/view/Forum_page.py @@ -1,3 +1,5 @@ +import os.path +import cherrypy from Product_page import Product_page from Page_navigation import Page_navigation from Tags import Div, H1, A, P @@ -8,7 +10,12 @@ class Forum_page( Product_page ): self, user, notebooks, first_notebook, login_url, logout_url, rate_plan, groups, forum_name, threads, total_thread_count, start = 0, count = None, ): - full_forum_name = "%s forum" % forum_name + base_path = cherrypy.request.path + + if base_path.startswith( u"/forums/" ): + full_forum_name = u"%s forum" % forum_name + else: + full_forum_name = u"Luminotes %s" % forum_name Product_page.__init__( self, @@ -22,19 +29,19 @@ class Forum_page( Product_page ): H1( full_forum_name ), ), Div( - P( - A( u"start a new discussion", href = u"/forums/%s/create_thread" % forum_name ), + base_path.startswith( u"/forums/" ) and P( + A( u"start a new discussion", href = os.path.join( base_path, u"create_thread" ) ), u" | ", A( u"all forums", href = u"/forums/" ), class_ = u"small_text", - ), + ) or None, [ Div( A( thread.name, - href = u"/forums/%s/%s" % ( forum_name, thread.object_id ), + href = os.path.join( base_path, thread.object_id ), ), ) for thread in threads ], class_ = u"forum_threads", ), - Page_navigation( u"/forums/%s" % forum_name, len( threads ), total_thread_count, start, count ), + Page_navigation( base_path, len( threads ), total_thread_count, start, count ), ) diff --git a/view/Product_page.py b/view/Product_page.py index 67f87a8..c40a66a 100644 --- a/view/Product_page.py +++ b/view/Product_page.py @@ -45,7 +45,7 @@ class Product_page( Page ): Li( u"Community", class_ = u"footer_category" ), Li( A( u"contact support", href = u"/contact_info" ) ), Li( A( u"discussion forums", href = u"/forums/" ) ), - Li( A( u"blog", href = u"/blog" ) ), + Li( A( u"blog", href = u"/blog/" ) ), Li( A( u"Facebook group", href = u"http://www.facebook.com/pages/Luminotes-personal-wiki-notebook/17143857741" ) ), Li( A( u"Twitter stream", href = u"http://twitter.com/Luminotes" ) ), class_ = u"footer_list",