witten
/
luminotes
Archived
1
0
Fork 0
This repository has been archived on 2023-12-16. You can view files and clone it, but cannot push or open issues or pull requests.
luminotes/controller/Forums.py

184 lines
5.8 KiB
Python
Raw Normal View History

import cherrypy
from model.User import User
from model.Notebook import Notebook
from model.Tag import Tag
from Expose import expose
from Validate import validate, Valid_string
from Database import Valid_id, end_transaction
from Users import grab_user_id
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.Main_page import Main_page
class Forums( object ):
"""
Controller for dealing with discussion forums, corresponding to the "/forums" URL.
"""
def __init__( self, database, notebooks, users ):
"""
Create a new Forums object, representing a collection of forums.
@type database: controller.Database
@param database: database that forums are stored in
@type notebooks: controller.Users
@param notebooks: controller for all notebooks
@type users: controller.Users
@param users: controller for all users
@rtype: Forums
@return: newly constructed Forums
"""
self.__database = database
self.__notebooks = notebooks
self.__users = users
self.__general = Forum( database, notebooks, users, u"general" )
self.__support = Forum( database, notebooks, users, u"support" )
@expose( view = Forums_page )
@end_transaction
@grab_user_id
@validate(
user_id = Valid_id( none_okay = True ),
)
def index( self, user_id ):
"""
Provide the information necessary to display the listing of available forums (currently hard-coded).
@type user_id: unicode or NoneType
@param user_id: id of the current user
"""
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:
result[ "first_notebook" ] = parents[ 0 ]
else:
result[ "first_notebook" ] = None
return result
general = property( lambda self: self.__general )
support = property( lambda self: self.__support )
class Forum( object ):
def __init__( self, database, notebooks, users, name ):
"""
Create a new Forum object, representing a single forum.
@type database: controller.Database
@param database: database that forums are stored in
@type notebooks: controller.Users
@param notebooks: controller for all notebooks
@type users: controller.Users
@param users: controller for all users
@type name: unicode
@param name: one-word name of this forum
@rtype: Forums
@return: newly constructed Forums
"""
self.__database = database
self.__notebooks = notebooks
self.__users = users
self.__name = name
@expose( view = Forum_page )
@end_transaction
@grab_user_id
@validate(
user_id = Valid_id( none_okay = True ),
)
def index( self, user_id ):
"""
Provide the information necessary to display the current threads within a forum.
@type user_id: unicode or NoneType
@param user_id: id of the current user
"""
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:
result[ "first_notebook" ] = parents[ 0 ]
else:
result[ "first_notebook" ] = None
anonymous = self.__database.select_one( User, User.sql_load_by_username( u"anonymous" ), use_cache = True )
if anonymous is None:
raise Access_error()
# TODO: this needs to sort by either thread/note creation or modification date
threads = self.__database.select_many(
Notebook,
anonymous.sql_load_notebooks(
parents_only = False, undeleted_only = True, tag_name = u"forum", tag_value = self.__name
)
)
# if there are no matching threads, then this forum doesn't exist
if len( threads ) == 0:
raise cherrypy.NotFound
result[ "forum_name" ] = self.__name
result[ "threads" ] = threads
return result
# default() is just an alias for Notebooks.default()
def default( self, *args, **kwargs ):
return self.__notebooks.default( *args, **kwargs )
default.exposed = True
@expose()
@end_transaction
@grab_user_id
@validate(
user_id = Valid_id( none_okay = True ),
)
def create_thread( self, user_id ):
"""
Create a new forum post and give it a default name. Then redirect to that new post thread.
@type user_id: unicode or NoneType
@param user_id: id of current logged-in user (if any)
@rtype dict
@return { 'redirect': new_notebook_url }
@raise Access_error: the current user doesn't have access to create a post
@raise Validation_error: one of the arguments is invalid
"""
if user_id is None:
raise Access_error()
user = self.__database.load( User, user_id )
if user is None or not user.username or user.username == "anonymous":
raise Access_error()
anonymous = self.__database.select_one( User, User.sql_load_by_username( u"anonymous" ), use_cache = True )
if anonymous is None:
raise Access_error()
# create the new notebook thread
thread_id = self.__database.next_id( Notebook, commit = False )
thread = Notebook.create( thread_id, u"new forum post", user_id = user.object_id )
self.__database.save( thread, commit = False )
# associate the forum tag with the new notebook thread
tag = self.__database.select_one( Tag, Tag.sql_load_by_name( u"forum", user_id = anonymous.object_id ) )
self.__database.execute(
anonymous.sql_save_notebook_tag( thread_id, tag.object_id, value = self.__name ),
commit = False,
)
# give the anonymous user access to the new notebook thread
self.__database.execute(
anonymous.sql_save_notebook( thread_id, read_write = True, owner = False, own_notes_only = True ),
commit = False,
)
self.__database.commit()
return dict(
redirect = u"/forums/%s/%s" % ( self.__name, thread_id ),
)