witten
/
luminotes
Archived
1
0
Fork 0

Lots of discussion forum / blog work.

This commit is contained in:
Dan Helfman 2008-11-18 13:28:51 -08:00
parent 4855ac0c7e
commit c211456130
9 changed files with 296 additions and 98 deletions

7
NEWS
View File

@ -6,10 +6,17 @@
* 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.
* You can now subscribe to an RSS feed in order to follow a whole Luminotes
discussion forum.
* The listing of threads in a discussion forum now shows how many posts
there are in each thread.
* 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
make the note reappear, even though the undeletion always worked.
* NOTE: After upgrading to this release, you must restart memcached to clear
the cache. Failing to do so will cause errors with the Notebook object.
This does not apply to Luminotes Desktop.
1.5.6: November 12, 2008
* Greatly improved the speed of wiki searching for Luminotes Server and

View File

@ -13,6 +13,7 @@ from Notebooks import Notebooks
from Users import Access_error
from view.Forums_page import Forums_page
from view.Forum_page import Forum_page
from view.Forum_rss import Forum_rss
from view.Main_page import Main_page
@ -90,7 +91,7 @@ class Forum( object ):
self.__users = users
self.__name = name
@expose( view = Forum_page )
@expose( view = Forum_page, rss = Forum_rss )
@strongly_expire
@end_transaction
@grab_user_id
@ -102,8 +103,7 @@ class Forum( object ):
)
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).
Provide the information necessary to display the current threads within a forum.
@type start: integer or NoneType
@param start: index of first forum thread to display (optional, defaults to 0)
@ -130,19 +130,12 @@ 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 = reverse,
exclude_notebook_name = self.DEFAULT_THREAD_NAME, reverse = True,
start = start, count = count,
)
)
@ -263,6 +256,11 @@ class Forum( object ):
self.__database.commit()
if self.__name == "blog":
return dict(
redirect = u"/blog/%s" % thread_id,
)
return dict(
redirect = u"/forums/%s/%s" % ( self.__name, thread_id ),
)

View File

@ -125,19 +125,17 @@ class Notebooks( object ):
result[ u"notebooks" ] = [
notebook for notebook in result[ "notebooks" ] if notebook.object_id == notebook_id
]
if len( result[ u"notebooks" ] ) == 0:
raise Access_error()
result[ u"notebooks" ][ 0 ].owner = False
if len( result[ u"notebooks" ] ) == 1:
result[ u"notebooks" ][ 0 ].owner = False
elif preview == u"viewer":
read_write = False
owner = False
result[ u"notebooks" ] = [
notebook for notebook in result[ "notebooks" ] if notebook.object_id == notebook_id
]
if len( result[ u"notebooks" ] ) == 0:
raise Access_error()
result[ u"notebooks" ][ 0 ].read_write = Notebook.READ_ONLY
result[ u"notebooks" ][ 0 ].owner = False
if len( result[ u"notebooks" ] ) == 1:
result[ u"notebooks" ][ 0 ].read_write = Notebook.READ_ONLY
result[ u"notebooks" ][ 0 ].owner = False
elif preview in ( u"owner", u"default", None ):
read_write = True
owner = True
@ -155,7 +153,10 @@ class Notebooks( object ):
forum_tags = [ tag for tag in notebook.tags if tag.name == u"forum" ]
if forum_tags:
forum_name = forum_tags[ 0 ].value
redirect = u"/forums/%s/%s" % ( forum_name, notebook_id )
if forum_name == "blog":
redirect = u"/blog/%s" % notebook_id
else:
redirect = u"/forums/%s/%s" % ( forum_name, notebook_id )
if note_id:
redirect += u"?note_id=%s" % note_id

View File

@ -15,7 +15,7 @@ class Test_forums( Test_controller ):
self.notebook = Notebook.create( self.database.next_id( Notebook ), u"my notebook", trash_id = u"foo" )
self.database.save( self.notebook )
self.anon_notebook = Notebook.create( self.database.next_id( Notebook ), u"Luminotes" )
self.anon_notebook = Notebook.create( self.database.next_id( Notebook ), u"Luminotes", trash_id = u"bar" )
self.database.save( self.anon_notebook )
self.anon_note = Note.create(
self.database.next_id( Note ), u"<h3>my note</h3>",
@ -43,6 +43,9 @@ class Test_forums( Test_controller ):
self.database.save( self.anonymous )
self.database.execute( self.anonymous.sql_save_notebook( self.anon_notebook.object_id ) )
self.blog_user = User.create( self.database.next_id( User ), u"witten", self.password, self.email_address )
self.database.save( self.blog_user )
tag_id = self.database.next_id( Tag )
self.forum_tag = Tag.create(
tag_id,
@ -71,14 +74,26 @@ class Test_forums( Test_controller ):
self.anonymous.sql_save_notebook_tag( self.support_thread.object_id, self.forum_tag.object_id, value = u"support" ),
)
self.blog_thread = Notebook.create( self.database.next_id( Notebook ), u"Welcome to the blog!" )
self.database.save( self.blog_thread )
self.database.execute(
self.anonymous.sql_save_notebook( self.blog_thread.object_id, read_write = Notebook.READ_WRITE_FOR_OWN_NOTES ),
)
self.database.execute(
self.blog_user.sql_save_notebook( self.blog_thread.object_id, read_write = Notebook.READ_WRITE ),
)
self.database.execute(
self.anonymous.sql_save_notebook_tag( self.blog_thread.object_id, self.forum_tag.object_id, value = u"forum" ),
)
def test_index( self ):
result = self.http_get( "/forums/" )
assert result
assert result.get( u"redirect" ) is None
assert result[ u"user" ].username == u"anonymous"
assert len( result[ u"notebooks" ] ) == 3
assert result[ u"first_notebook" ] == None
assert len( result[ u"notebooks" ] ) == 4
assert result[ u"first_notebook" ].object_id == self.anon_notebook.object_id
assert result[ u"login_url" ] == u"https://luminotes.com/notebooks/%s?note_id=%s" % (
self.anon_notebook.object_id, self.login_note.object_id,
)
@ -93,7 +108,7 @@ class Test_forums( Test_controller ):
assert result
assert result.get( u"redirect" ) is None
assert result[ u"user" ].username == self.user.username
assert len( result[ u"notebooks" ] ) == 4
assert len( result[ u"notebooks" ] ) == 5
assert result[ u"first_notebook" ].object_id == self.notebook.object_id
assert result[ u"login_url" ] == None
assert result[ u"logout_url" ] == u"https://luminotes.com/users/logout"
@ -123,6 +138,18 @@ class Test_forums( Test_controller ):
assert result[ u"count" ] == 50
assert result[ u"total_thread_count" ] == 1
def test_general_with_note_id( self ):
result = self.http_get( "/forums/general?note_id=blah" )
headers = result.get( "headers" )
assert headers
assert headers.get( "Location" ) == u"http:///forums/general/?note_id=blah"
def test_general_with_trailing_slash_and_note_id( self ):
result = self.http_get( "/forums/general/?note_id=blah" )
assert result.get( "redirect" ) == u"/forums/general/blah"
def test_support( self ):
result = self.http_get( "/forums/support/" )
@ -223,7 +250,7 @@ class Test_forums( Test_controller ):
result = self.http_get( "/forums/general/%s" % self.general_thread.object_id )
assert result.get( u"user" ).object_id == self.anonymous.object_id
assert len( result.get( u"notebooks" ) ) == 3
assert len( result.get( u"notebooks" ) ) == 4
assert result.get( u"notebooks" )[ 0 ].object_id == self.anon_notebook.object_id
assert result.get( u"login_url" )
assert result.get( u"logout_url" )
@ -250,7 +277,7 @@ class Test_forums( Test_controller ):
)
assert result.get( u"user" ).object_id == self.user.object_id
assert len( result.get( u"notebooks" ) ) == 4
assert len( result.get( u"notebooks" ) ) == 5
assert result.get( u"notebooks" )[ 0 ].object_id == self.notebook.object_id
assert result.get( u"login_url" ) is None
assert result.get( u"logout_url" )
@ -322,7 +349,7 @@ class Test_forums( Test_controller ):
result = self.http_get( "/forums/general/%s" % self.general_thread.object_id )
assert result.get( u"user" ).object_id == self.anonymous.object_id
assert len( result.get( u"notebooks" ) ) == 3
assert len( result.get( u"notebooks" ) ) == 4
assert result.get( u"notebooks" )[ 0 ].object_id == self.anon_notebook.object_id
assert result.get( u"login_url" )
assert result.get( u"logout_url" )
@ -352,7 +379,7 @@ class Test_forums( Test_controller ):
result = self.http_get( "/forums/general/%s?start=1" % self.general_thread.object_id )
assert result.get( u"user" ).object_id == self.anonymous.object_id
assert len( result.get( u"notebooks" ) ) == 3
assert len( result.get( u"notebooks" ) ) == 4
assert result.get( u"notebooks" )[ 0 ].object_id == self.anon_notebook.object_id
assert result.get( u"login_url" )
assert result.get( u"logout_url" )
@ -381,7 +408,7 @@ class Test_forums( Test_controller ):
result = self.http_get( "/forums/general/%s?count=2" % self.general_thread.object_id )
assert result.get( u"user" ).object_id == self.anonymous.object_id
assert len( result.get( u"notebooks" ) ) == 3
assert len( result.get( u"notebooks" ) ) == 4
assert result.get( u"notebooks" )[ 0 ].object_id == self.anon_notebook.object_id
assert result.get( u"login_url" )
assert result.get( u"logout_url" )
@ -410,7 +437,7 @@ class Test_forums( Test_controller ):
result = self.http_get( "/forums/general/%s?start=1&count=1" % self.general_thread.object_id )
assert result.get( u"user" ).object_id == self.anonymous.object_id
assert len( result.get( u"notebooks" ) ) == 3
assert len( result.get( u"notebooks" ) ) == 4
assert result.get( u"notebooks" )[ 0 ].object_id == self.anon_notebook.object_id
assert result.get( u"login_url" )
assert result.get( u"logout_url" )
@ -438,7 +465,7 @@ class Test_forums( Test_controller ):
result = self.http_get( "/forums/general/%s?note_id=%s" % ( self.general_thread.object_id, self.note.object_id ) )
assert result.get( u"user" ).object_id == self.anonymous.object_id
assert len( result.get( u"notebooks" ) ) == 3
assert len( result.get( u"notebooks" ) ) == 4
assert result.get( u"notebooks" )[ 0 ].object_id == self.anon_notebook.object_id
assert result.get( u"login_url" )
assert result.get( u"logout_url" )
@ -461,7 +488,7 @@ class Test_forums( Test_controller ):
user = self.database.load( User, self.user.object_id )
assert user.storage_bytes == 0
def __assert_new_forum_thread( self, thread, expected_id ):
def __assert_new_forum_thread( self, thread, expected_id, expected_user_id = None ):
assert thread
assert thread.object_id == expected_id
assert thread.name == u"new discussion"
@ -469,7 +496,7 @@ class Test_forums( Test_controller ):
assert thread.read_write == Notebook.READ_WRITE_FOR_OWN_NOTES
assert thread.owner == False
assert thread.deleted == False
assert thread.user_id == self.user.object_id
assert thread.user_id == ( expected_user_id or self.user.object_id )
def test_general_create_thread( self ):
self.login()
@ -517,6 +544,62 @@ class Test_forums( Test_controller ):
assert headers
assert headers.get( "Location" ) == u"http:///login?after_login=%s" % urllib.quote( path )
def test_blog_create_thread( self ):
self.login_blog()
result = self.http_get(
"/blog/create_thread",
session_id = self.session_id,
)
redirect = result.get( u"redirect" )
assert redirect
assert redirect.startswith( u"/blog/" )
new_thread_id = redirect.split( "/blog/" )[ -1 ].split( u"?" )[ 0 ]
thread = cherrypy.root.users.load_notebook( self.blog_user.object_id, new_thread_id, read_write = True )
self.__assert_new_forum_thread( thread, new_thread_id, self.blog_user.object_id )
tags = self.database.select_many( Tag, thread.sql_load_tags( self.blog_user.object_id ) )
assert tags == []
thread = cherrypy.root.users.load_notebook( self.anonymous.object_id, new_thread_id, read_write = False )
self.__assert_new_forum_thread( thread, new_thread_id, self.blog_user.object_id )
tags = self.database.select_many( Tag, thread.sql_load_tags( self.anonymous.object_id ) )
assert tags
assert len( tags ) == 1
assert tags[ 0 ].name == u"forum"
assert tags[ 0 ].value == u"blog"
notes = self.database.select_many( Note, thread.sql_load_notes() )
assert notes
assert len( notes ) == 1
assert notes[ 0 ].title == None
assert notes[ 0 ].contents == u"<h3>"
assert notes[ 0 ].notebook_id == thread.object_id
assert notes[ 0 ].startup is True
assert notes[ 0 ].deleted_from_id is None
assert notes[ 0 ].rank == 0
assert notes[ 0 ].user_id == self.blog_user.object_id
def test_blog_create_thread_without_login( self ):
path = "/blog/create_thread"
result = self.http_get( path )
headers = result.get( "headers" )
assert headers
assert headers.get( "Location" ) == u"http:///login?after_login=%s" % urllib.quote( path )
def test_blog_create_thread_without_access( self ):
self.login()
result = self.http_get(
"/blog/create_thread",
session_id = self.session_id,
)
assert u"access" in result[ u"body" ][ 0 ]
def login( self ):
result = self.http_post( "/users/login", dict(
username = self.username,
@ -532,3 +615,12 @@ class Test_forums( Test_controller ):
login_button = u"login",
) )
self.session_id = result[ u"session_id" ]
def login_blog( self ):
result = self.http_post( "/users/login", dict(
username = self.blog_user.username,
password = self.password,
login_button = u"login",
) )
self.session_id = result[ u"session_id" ]

View File

@ -192,6 +192,33 @@ class Test_notebooks( Test_controller ):
redirect = result.get( "redirect" )
assert redirect == u"/forums/chickens/%s" % self.notebook.object_id
def test_default_blog( self ):
self.login()
tag_id = self.database.next_id( Tag, commit = False )
new_tag = Tag.create(
tag_id,
notebook_id = None, # this tag is not in the namespace of a single notebook
user_id = self.user.object_id,
name = u"forum",
description = u"a discussion forum"
)
self.database.save( new_tag, commit = False )
self.database.execute(
self.user.sql_save_notebook_tag( self.notebook.object_id, new_tag.object_id, value = u"blog" ),
commit = False,
)
self.database.commit()
result = self.http_get(
"/notebooks/%s" % self.notebook.object_id,
session_id = self.session_id,
)
redirect = result.get( "redirect" )
assert redirect == u"/blog/%s" % self.notebook.object_id
def test_default( self ):
self.login()
@ -201,10 +228,10 @@ class Test_notebooks( Test_controller ):
)
assert result.get( u"user" ).object_id == self.user.object_id
assert len( result.get( u"notebooks" ) ) == 3
assert result.get( u"notebooks" )[ 2 ].object_id == self.notebook.object_id
assert result.get( u"notebooks" )[ 2 ].read_write == Notebook.READ_WRITE
assert result.get( u"notebooks" )[ 2 ].owner == True
assert len( result.get( u"notebooks" ) ) == 1
assert result.get( u"notebooks" )[ 0 ].object_id == self.notebook.object_id
assert result.get( u"notebooks" )[ 0 ].read_write == Notebook.READ_WRITE
assert result.get( u"notebooks" )[ 0 ].owner == True
assert result.get( u"login_url" ) is None
assert result.get( u"logout_url" )
assert result.get( u"rate_plan" )
@ -309,10 +336,10 @@ class Test_notebooks( Test_controller ):
)
assert result.get( u"user" ).object_id == self.user.object_id
assert len( result.get( u"notebooks" ) ) == 3
assert result.get( u"notebooks" )[ 2 ].object_id == self.notebook.object_id
assert result.get( u"notebooks" )[ 2 ].read_write == Notebook.READ_WRITE
assert result.get( u"notebooks" )[ 2 ].owner == True
assert len( result.get( u"notebooks" ) ) == 1
assert result.get( u"notebooks" )[ 0 ].object_id == self.notebook.object_id
assert result.get( u"notebooks" )[ 0 ].read_write == Notebook.READ_WRITE
assert result.get( u"notebooks" )[ 0 ].owner == True
assert result.get( u"login_url" ) is None
assert result.get( u"logout_url" )
assert result.get( u"rate_plan" )
@ -345,10 +372,7 @@ class Test_notebooks( Test_controller ):
)
assert result.get( u"user" ).object_id == self.user.object_id
assert len( result.get( u"notebooks" ) ) == 1
assert result.get( u"notebooks" )[ 0 ].object_id == self.anon_notebook.object_id
assert result.get( u"notebooks" )[ 0 ].read_write == Notebook.READ_ONLY
assert result.get( u"notebooks" )[ 0 ].owner == False
assert len( result.get( u"notebooks" ) ) == 0
assert result.get( u"login_url" ) is None
assert result.get( u"logout_url" )
assert result.get( u"rate_plan" )
@ -377,10 +401,7 @@ class Test_notebooks( Test_controller ):
# even though a collaborator preview is being requested, this user only has preview-level
# access. so read_write should be False on the returned notebook
assert result.get( u"user" ).object_id == self.user.object_id
assert len( result.get( u"notebooks" ) ) == 1
assert result.get( u"notebooks" )[ 0 ].object_id == self.anon_notebook.object_id
assert result.get( u"notebooks" )[ 0 ].read_write == Notebook.READ_ONLY
assert result.get( u"notebooks" )[ 0 ].owner == False
assert len( result.get( u"notebooks" ) ) == 0
assert result.get( u"login_url" ) is None
assert result.get( u"logout_url" )
assert result.get( u"rate_plan" )
@ -407,14 +428,12 @@ class Test_notebooks( Test_controller ):
)
assert result.get( u"user" ).object_id == self.user.object_id
assert len( result.get( u"notebooks" ) ) == 3
assert len( result.get( u"notebooks" ) ) == 1
notebook = result[ u"notebooks" ][ 0 ]
if notebook.name == u"trash":
notebook = result[ u"notebooks" ][ 1 ]
assert notebook.object_id == self.anon_notebook.object_id
assert notebook.read_write == Notebook.READ_ONLY
assert notebook.owner == False
assert notebook.object_id == self.notebook.object_id
assert notebook.read_write == Notebook.READ_WRITE
assert notebook.owner == True
assert result.get( u"login_url" ) is None
assert result.get( u"logout_url" )
assert result.get( u"rate_plan" )
@ -498,10 +517,10 @@ class Test_notebooks( Test_controller ):
)
assert result.get( u"user" ).object_id == self.user.object_id
assert len( result.get( u"notebooks" ) ) == 3
assert result.get( u"notebooks" )[ 2 ].object_id == self.notebook.object_id
assert result.get( u"notebooks" )[ 2 ].read_write == Notebook.READ_WRITE
assert result.get( u"notebooks" )[ 2 ].owner == True
assert len( result.get( u"notebooks" ) ) == 1
assert result.get( u"notebooks" )[ 0 ].object_id == self.notebook.object_id
assert result.get( u"notebooks" )[ 0 ].read_write == Notebook.READ_WRITE
assert result.get( u"notebooks" )[ 0 ].owner == True
assert result.get( u"login_url" ) is None
assert result.get( u"logout_url" )
assert result.get( u"rate_plan" )
@ -541,10 +560,10 @@ class Test_notebooks( Test_controller ):
)
assert result.get( u"user" ).object_id == self.user.object_id
assert len( result.get( u"notebooks" ) ) == 3
assert result.get( u"notebooks" )[ 2 ].object_id == self.notebook.object_id
assert result.get( u"notebooks" )[ 2 ].read_write == Notebook.READ_WRITE
assert result.get( u"notebooks" )[ 2 ].owner == True
assert len( result.get( u"notebooks" ) ) == 1
assert result.get( u"notebooks" )[ 0 ].object_id == self.notebook.object_id
assert result.get( u"notebooks" )[ 0 ].read_write == Notebook.READ_WRITE
assert result.get( u"notebooks" )[ 0 ].owner == True
assert result.get( u"login_url" ) is None
assert result.get( u"logout_url" )
assert result.get( u"rate_plan" )
@ -590,10 +609,10 @@ class Test_notebooks( Test_controller ):
)
assert result.get( u"user" ).object_id == self.user.object_id
assert len( result.get( u"notebooks" ) ) == 3
assert result.get( u"notebooks" )[ 2 ].object_id == self.notebook.object_id
assert result.get( u"notebooks" )[ 2 ].read_write == Notebook.READ_WRITE
assert result.get( u"notebooks" )[ 2 ].owner == True
assert len( result.get( u"notebooks" ) ) == 1
assert result.get( u"notebooks" )[ 0 ].object_id == self.notebook.object_id
assert result.get( u"notebooks" )[ 0 ].read_write == Notebook.READ_WRITE
assert result.get( u"notebooks" )[ 0 ].owner == True
assert result.get( u"login_url" ) is None
assert result.get( u"logout_url" )
assert result.get( u"rate_plan" )
@ -632,10 +651,10 @@ class Test_notebooks( Test_controller ):
)
assert result.get( u"user" ).object_id == self.user.object_id
assert len( result.get( u"notebooks" ) ) == 3
assert result.get( u"notebooks" )[ 2 ].object_id == self.notebook.object_id
assert result.get( u"notebooks" )[ 2 ].read_write == Notebook.READ_WRITE
assert result.get( u"notebooks" )[ 2 ].owner == True
assert len( result.get( u"notebooks" ) ) == 1
assert result.get( u"notebooks" )[ 0 ].object_id == self.notebook.object_id
assert result.get( u"notebooks" )[ 0 ].read_write == Notebook.READ_WRITE
assert result.get( u"notebooks" )[ 0 ].owner == True
assert result.get( u"login_url" ) is None
assert result.get( u"logout_url" )
assert result.get( u"rate_plan" )
@ -4749,7 +4768,7 @@ class Test_notebooks( Test_controller ):
)
assert result.get( u"user" ).object_id == self.user.object_id
assert len( result.get( u"notebooks" ) ) == 3
assert len( result.get( u"notebooks" ) ) == 1
assert result.get( u"login_url" ) is None
assert result.get( u"logout_url" )
assert result.get( u"rate_plan" )
@ -4779,7 +4798,7 @@ class Test_notebooks( Test_controller ):
)
assert result.get( u"user" ).object_id == self.user.object_id
assert len( result.get( u"notebooks" ) ) == 3
assert len( result.get( u"notebooks" ) ) == 1
assert result.get( u"login_url" ) is None
assert result.get( u"logout_url" )
assert result.get( u"rate_plan" )
@ -4808,7 +4827,7 @@ class Test_notebooks( Test_controller ):
)
assert result.get( u"user" ).object_id == self.user.object_id
assert len( result.get( u"notebooks" ) ) == 3
assert len( result.get( u"notebooks" ) ) == 1
assert result.get( u"login_url" ) is None
assert result.get( u"logout_url" )
assert result.get( u"rate_plan" )
@ -4850,7 +4869,7 @@ class Test_notebooks( Test_controller ):
)
assert result.get( u"user" ).object_id == self.user.object_id
assert len( result.get( u"notebooks" ) ) == 3
assert len( result.get( u"notebooks" ) ) == 1
assert result.get( u"login_url" ) is None
assert result.get( u"logout_url" )
assert result.get( u"rate_plan" )
@ -4880,7 +4899,7 @@ class Test_notebooks( Test_controller ):
)
assert result.get( u"user" ).object_id == self.user.object_id
assert len( result.get( u"notebooks" ) ) == 3
assert len( result.get( u"notebooks" ) ) == 1
assert result.get( u"login_url" ) is None
assert result.get( u"logout_url" )
assert result.get( u"rate_plan" )
@ -4909,7 +4928,7 @@ class Test_notebooks( Test_controller ):
)
assert result.get( u"user" ).object_id == self.user.object_id
assert len( result.get( u"notebooks" ) ) == 3
assert len( result.get( u"notebooks" ) ) == 1
assert result.get( u"login_url" ) is None
assert result.get( u"logout_url" )
assert result.get( u"rate_plan" )

View File

@ -1,8 +1,9 @@
import os.path
import cherrypy
from datetime import datetime
from Product_page import Product_page
from Page_navigation import Page_navigation
from Tags import Div, H1, A, P
from Tags import Div, H1, A, P, Span, Link, Img
class Forum_page( Product_page ):
@ -11,11 +12,12 @@ class Forum_page( Product_page ):
threads, total_thread_count, start = 0, count = None,
):
base_path = cherrypy.request.path
updates_path = "%s?rss" % base_path
if base_path.startswith( u"/forums/" ):
full_forum_name = u"%s forum" % forum_name
else:
if forum_name == u"blog":
full_forum_name = u"Luminotes %s" % forum_name
else:
full_forum_name = u"%s forum" % forum_name
Product_page.__init__(
self,
@ -24,15 +26,24 @@ class Forum_page( Product_page ):
login_url,
logout_url,
full_forum_name, # note title
Link( rel = u"alternate", type = u"application/rss+xml", title = full_forum_name, href = updates_path ) or None,
P(
H1( full_forum_name ),
),
Div(
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/" ),
P(
base_path.startswith( u"/forums/" ) and Span(
A( u"start a new discussion", href = os.path.join( base_path, u"create_thread" ) ),
u" | ",
A( u"all forums", href = u"/forums/" ),
u" | ",
) or None,
A( u"subscribe to rss", href = updates_path ),
A(
Img( src = u"/static/images/rss.png", width = u"14", height = u"14", class_ = u"middle_image padding_left" ),
href = updates_path,
),
class_ = u"small_text",
) or None,
[ Div(
@ -40,8 +51,26 @@ class Forum_page( Product_page ):
thread.name,
href = os.path.join( base_path, thread.object_id ),
),
Span(
self.post_count( thread, forum_name ),
class_ = u"small_text",
)
) for thread in threads ],
class_ = u"forum_threads",
),
Page_navigation( base_path, len( threads ), total_thread_count, start, count ),
)
@staticmethod
def post_count( thread, forum_name ):
if forum_name != u"blog":
if thread.note_count > 1:
return u"(%s posts)" % thread.note_count
return None
if thread.note_count == 2:
return u"(1 comment)"
elif thread.note_count > 2:
return u"(%s comments)" % ( thread.note_count - 1 )
return None

42
view/Forum_rss.py Normal file
View File

@ -0,0 +1,42 @@
import cgi
import os.path
import cherrypy
from Rss_channel import Rss_channel
from Rss_item import Rss_item
class Forum_rss( Rss_channel ):
def __init__(
self,
user,
notebooks,
first_notebook,
login_url,
logout_url,
rate_plan,
groups,
forum_name,
threads,
total_thread_count,
start = 0,
count = None,
):
forum_path = cherrypy.request.base + cherrypy.request.path
if forum_name == u"blog":
full_forum_name = u"Luminotes %s" % forum_name
else:
full_forum_name = u"%s forum" % forum_name
Rss_channel.__init__(
self,
full_forum_name,
forum_path,
full_forum_name,
[ Rss_item(
title = cgi.escape( thread.name ),
link = os.path.join( forum_path, thread.object_id ),
description = cgi.escape( thread.name ),
date = thread.revision.strftime( "%Y-%m-%dT%H:%M:%SZ" ),
guid = os.path.join( forum_path, thread.object_id ),
) for thread in threads ],
)

View File

@ -28,16 +28,14 @@ class Link_area( Div ):
Div.__init__(
self,
toolbar,
( user.username == u"anonymous" ) and self.forum_link( forum_tag, forum_name ) or None,
( user.username != u"anonymous" ) and Div(
( notebook_path != u"/" ) and Div(
H4(
u"this %s" % notebook_word,
id = u"this_notebook_area_title",
),
forum_tag and Div(
A( u"%s forum" % forum_name, href = "/forums/%s" % forum_name ),
class_ = u"link_area_item",
) or None,
self.forum_link( forum_tag, forum_name ),
( rate_plan.get( u"notebook_sharing" ) and notebook.name == u"Luminotes blog" ) and Div(
A(
@ -208,3 +206,19 @@ class Link_area( Div ):
) or None,
id = u"link_area",
)
@staticmethod
def forum_link( forum_tag, forum_name ):
if not forum_tag:
return None
if forum_name == u"blog":
return Div(
A( u"Luminotes %s" % forum_name, href = "/blog/" ),
class_ = u"link_area_item",
)
return Div(
A( u"%s forum" % forum_name, href = "/forums/%s" % forum_name ),
class_ = u"link_area_item",
)

View File

@ -94,14 +94,13 @@ class Main_page( Page ):
updates_path = None
forum_tags = [ tag for tag in notebook.tags if tag.name == u"forum" ]
forum_tag = None
if notebook.name == u"Luminotes":
notebook_path = u"/"
updates_path = None # no RSS feed for the main notebook
elif notebook.name == u"Luminotes user guide":
notebook_path = u"/guide"
elif notebook.name == u"Luminotes blog":
notebook_path = u"/blog"
elif forum_tags:
forum_tag = forum_tags[ 0 ]
notebook_path = u"/forums/%s/%s" % ( forum_tag.value, notebook.object_id )
@ -125,7 +124,6 @@ class Main_page( Page ):
"contact info": "contact",
"meet the team": "team",
"Luminotes user guide": "guide",
"Luminotes blog": "blog",
"Luminotes privacy policy": "privacy",
}.get( header_note_title, header_note_title )
@ -136,10 +134,8 @@ class Main_page( Page ):
self,
title,
Link( rel = u"stylesheet", type = u"text/css", href = u"/static/css/header.css" ),
( notebook.name == u"Luminotes blog" ) \
and Link( rel = u"alternate", type = u"application/rss+xml", title = u"Luminotes blog", href = "/blog?rss" ) \
or ( updates_path and \
Link( rel = u"alternate", type = u"application/rss+xml", title = notebook.name, href = updates_path ) or None ),
updates_path and \
Link( rel = u"alternate", type = u"application/rss+xml", title = notebook.name, href = updates_path ) or None,
Script( type = u"text/javascript", src = u"/static/js/MochiKit.js" ) or None,
Script( type = u"text/javascript", src = u"/static/js/Invoker.js" ) or None,
Script( type = u"text/javascript", src = u"/static/js/Editor.js" ) or None,
@ -170,7 +166,7 @@ class Main_page( Page ):
Toolbar(
notebook,
hide_toolbar = parent_id or notebook.read_write == Notebook.READ_ONLY,
note_word = ( notebook.read_write == Notebook.READ_WRITE_FOR_OWN_NOTES ) and u"post" or u"note",
note_word = forum_tag and u"post" or u"note",
),
notebooks, notebook, parent_id, notebook_path, updates_path, user, rate_plan,
),
@ -212,8 +208,6 @@ class Main_page( Page ):
Page_navigation(
notebook_path, len( notes ), total_notes_count, start, count,
),
( notebook.read_write == Notebook.READ_WRITE_FOR_OWN_NOTES and user.username and user.username != u"anonymous" ) and \
P( u"If you write a comment, click the save button to publish it.", class_ = u"small_text" ) or None,
Div(
Span( id = u"notes_top" ),
id = u"notes",
@ -231,6 +225,8 @@ class Main_page( Page ):
u"document.getElementById( 'static_notes' ).style.display = 'none';",
type = u"text/javascript",
),
( forum_tag and user.username and user.username != u"anonymous" ) and \
P( u"If you write a comment, click the save button to publish it.", class_ = u"small_text" ) or None,
Page_navigation(
notebook_path, len( notes ), total_notes_count, start, count,
return_text = u"return to the discussion",