Added ability to reorder notebooks on the right side of the page.
Need to complete unit tests for controller.Notebooks.move_up() and move_down().
This commit is contained in:
parent
68fe84b707
commit
94a51889f9
3
NEWS
3
NEWS
|
@ -1,3 +1,6 @@
|
||||||
|
1.2.14: March ??, 2008
|
||||||
|
* Added ability to reorder notebooks on the right side of the page.
|
||||||
|
|
||||||
1.2.13: March 11, 2008
|
1.2.13: March 11, 2008
|
||||||
* When the "all notes" note is the only note open, it now actually hides when
|
* When the "all notes" note is the only note open, it now actually hides when
|
||||||
the "hide" button is clicked.
|
the "hide" button is clicked.
|
||||||
|
|
|
@ -505,7 +505,7 @@ class Notebooks( object ):
|
||||||
note.startup = startup
|
note.startup = startup
|
||||||
if startup:
|
if startup:
|
||||||
if note.rank is None:
|
if note.rank is None:
|
||||||
note.rank = self.__database.select_one( float, notebook.sql_highest_rank() ) + 1
|
note.rank = self.__database.select_one( float, notebook.sql_highest_note_rank() ) + 1
|
||||||
else:
|
else:
|
||||||
note.rank = None
|
note.rank = None
|
||||||
note.user_id = user.object_id
|
note.user_id = user.object_id
|
||||||
|
@ -538,7 +538,7 @@ class Notebooks( object ):
|
||||||
# otherwise, create a new note
|
# otherwise, create a new note
|
||||||
else:
|
else:
|
||||||
if startup:
|
if startup:
|
||||||
rank = self.__database.select_one( float, notebook.sql_highest_rank() ) + 1
|
rank = self.__database.select_one( float, notebook.sql_highest_note_rank() ) + 1
|
||||||
else:
|
else:
|
||||||
rank = None
|
rank = None
|
||||||
|
|
||||||
|
@ -875,7 +875,8 @@ class Notebooks( object ):
|
||||||
self.__database.save( notebook, commit = False )
|
self.__database.save( notebook, commit = False )
|
||||||
|
|
||||||
# record the fact that the user has access to their new notebook
|
# record the fact that the user has access to their new notebook
|
||||||
self.__database.execute( user.sql_save_notebook( notebook_id, read_write = True, owner = True ), commit = False )
|
rank = self.__database.select_one( float, user.sql_highest_notebook_rank() ) + 1
|
||||||
|
self.__database.execute( user.sql_save_notebook( notebook_id, read_write = True, owner = True, rank = rank ), commit = False )
|
||||||
self.__database.execute( user.sql_save_notebook( trash_id, read_write = True, owner = True ), commit = False )
|
self.__database.execute( user.sql_save_notebook( trash_id, read_write = True, owner = True ), commit = False )
|
||||||
|
|
||||||
if commit:
|
if commit:
|
||||||
|
@ -1071,6 +1072,149 @@ class Notebooks( object ):
|
||||||
redirect = u"/notebooks/%s" % notebook.object_id,
|
redirect = u"/notebooks/%s" % notebook.object_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@expose( view = Json )
|
||||||
|
@grab_user_id
|
||||||
|
@validate(
|
||||||
|
notebook_id = Valid_id(),
|
||||||
|
user_id = Valid_id( none_okay = True ),
|
||||||
|
)
|
||||||
|
def move_up( self, notebook_id, user_id ):
|
||||||
|
"""
|
||||||
|
Reorder the user's notebooks by moving the given notebook up by one. If the notebook is already
|
||||||
|
first, then wrap it around to be the last notebook.
|
||||||
|
|
||||||
|
@type notebook_id: unicode
|
||||||
|
@param notebook_id: id of notebook to move up
|
||||||
|
@type user_id: unicode or NoneType
|
||||||
|
@param user_id: id of current logged-in user (if any)
|
||||||
|
@rtype json dict
|
||||||
|
@return {}
|
||||||
|
@raise Access_error: the current user doesn't have access to the given notebook
|
||||||
|
@raise Validation_error: one of the arguments is invalid
|
||||||
|
"""
|
||||||
|
if not self.__users.check_access( user_id, notebook_id ):
|
||||||
|
raise Access_error()
|
||||||
|
|
||||||
|
user = self.__database.load( User, user_id )
|
||||||
|
if not user:
|
||||||
|
raise Access_error()
|
||||||
|
|
||||||
|
# load the notebooks to which this user has access
|
||||||
|
notebooks = self.__database.select_many(
|
||||||
|
Notebook,
|
||||||
|
user.sql_load_notebooks( parents_only = True, undeleted_only = True ),
|
||||||
|
)
|
||||||
|
if not notebooks:
|
||||||
|
raise Access_error()
|
||||||
|
|
||||||
|
# find the given notebook and the one previous to it
|
||||||
|
previous_notebook = None
|
||||||
|
current_notebook = None
|
||||||
|
|
||||||
|
for notebook in notebooks:
|
||||||
|
if notebook.object_id == notebook_id:
|
||||||
|
current_notebook = notebook
|
||||||
|
break
|
||||||
|
previous_notebook = notebook
|
||||||
|
|
||||||
|
if current_notebook is None:
|
||||||
|
raise Access_error()
|
||||||
|
|
||||||
|
# if there is no previous notebook, then the current notebook is first. so, move it after the
|
||||||
|
# last notebook
|
||||||
|
if previous_notebook is None:
|
||||||
|
last_notebook = notebooks[ -1 ]
|
||||||
|
self.__database.execute(
|
||||||
|
user.sql_update_notebook_rank( current_notebook.object_id, last_notebook.rank + 1 ),
|
||||||
|
commit = False,
|
||||||
|
)
|
||||||
|
# otherwise, save the current and previous notebooks back to the database with swapped ranks
|
||||||
|
else:
|
||||||
|
self.__database.execute(
|
||||||
|
user.sql_update_notebook_rank( current_notebook.object_id, previous_notebook.rank ),
|
||||||
|
commit = False,
|
||||||
|
)
|
||||||
|
self.__database.execute(
|
||||||
|
user.sql_update_notebook_rank( previous_notebook.object_id, current_notebook.rank ),
|
||||||
|
commit = False,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.__database.commit()
|
||||||
|
|
||||||
|
return dict()
|
||||||
|
|
||||||
|
@expose( view = Json )
|
||||||
|
@grab_user_id
|
||||||
|
@validate(
|
||||||
|
notebook_id = Valid_id(),
|
||||||
|
user_id = Valid_id( none_okay = True ),
|
||||||
|
)
|
||||||
|
def move_down( self, notebook_id, user_id ):
|
||||||
|
"""
|
||||||
|
Reorder the user's notebooks by moving the given notebook down by one. If the notebook is
|
||||||
|
already last, then wrap it around to be the first notebook.
|
||||||
|
|
||||||
|
@type notebook_id: unicode
|
||||||
|
@param notebook_id: id of notebook to move down
|
||||||
|
@type user_id: unicode or NoneType
|
||||||
|
@param user_id: id of current logged-in user (if any)
|
||||||
|
@rtype json dict
|
||||||
|
@return {}
|
||||||
|
@raise Access_error: the current user doesn't have access to the given notebook
|
||||||
|
@raise Validation_error: one of the arguments is invalid
|
||||||
|
"""
|
||||||
|
if not self.__users.check_access( user_id, notebook_id ):
|
||||||
|
raise Access_error()
|
||||||
|
|
||||||
|
user = self.__database.load( User, user_id )
|
||||||
|
if not user:
|
||||||
|
raise Access_error()
|
||||||
|
|
||||||
|
# load the notebooks to which this user has access
|
||||||
|
notebooks = self.__database.select_many(
|
||||||
|
Notebook,
|
||||||
|
user.sql_load_notebooks( parents_only = True, undeleted_only = True ),
|
||||||
|
)
|
||||||
|
if not notebooks:
|
||||||
|
raise Access_error()
|
||||||
|
|
||||||
|
# find the given notebook and the one after it
|
||||||
|
current_notebook = None
|
||||||
|
next_notebook = None
|
||||||
|
|
||||||
|
for notebook in notebooks:
|
||||||
|
if notebook.object_id == notebook_id:
|
||||||
|
current_notebook = notebook
|
||||||
|
elif current_notebook:
|
||||||
|
next_notebook = notebook
|
||||||
|
break
|
||||||
|
|
||||||
|
if current_notebook is None:
|
||||||
|
raise Access_error()
|
||||||
|
|
||||||
|
# if there is no next notebook, then the current notebook is last. so, move it before the
|
||||||
|
# first notebook
|
||||||
|
if next_notebook is None:
|
||||||
|
first_notebook = notebooks[ 0 ]
|
||||||
|
self.__database.execute(
|
||||||
|
user.sql_update_notebook_rank( current_notebook.object_id, first_notebook.rank - 1 ),
|
||||||
|
commit = False,
|
||||||
|
)
|
||||||
|
# otherwise, save the current and next notebooks back to the database with swapped ranks
|
||||||
|
else:
|
||||||
|
self.__database.execute(
|
||||||
|
user.sql_update_notebook_rank( current_notebook.object_id, next_notebook.rank ),
|
||||||
|
commit = False,
|
||||||
|
)
|
||||||
|
self.__database.execute(
|
||||||
|
user.sql_update_notebook_rank( next_notebook.object_id, current_notebook.rank ),
|
||||||
|
commit = False,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.__database.commit()
|
||||||
|
|
||||||
|
return dict()
|
||||||
|
|
||||||
def load_recent_notes( self, notebook_id, start = 0, count = 10, user_id = None ):
|
def load_recent_notes( self, notebook_id, start = 0, count = 10, user_id = None ):
|
||||||
"""
|
"""
|
||||||
Provide the information necessary to display the page for a particular notebook's most recent
|
Provide the information necessary to display the page for a particular notebook's most recent
|
||||||
|
|
|
@ -262,7 +262,7 @@ class Users( object ):
|
||||||
self.__database.save( user, commit = False )
|
self.__database.save( user, commit = False )
|
||||||
|
|
||||||
# record the fact that the new user has access to their new notebook
|
# record the fact that the new user has access to their new notebook
|
||||||
self.__database.execute( user.sql_save_notebook( notebook_id, read_write = True, owner = True ), commit = False )
|
self.__database.execute( user.sql_save_notebook( notebook_id, read_write = True, owner = True, rank = 0 ), commit = False )
|
||||||
self.__database.execute( user.sql_save_notebook( trash_id, read_write = True, owner = True ), commit = False )
|
self.__database.execute( user.sql_save_notebook( trash_id, read_write = True, owner = True ), commit = False )
|
||||||
self.__database.commit()
|
self.__database.commit()
|
||||||
|
|
||||||
|
@ -335,7 +335,7 @@ class Users( object ):
|
||||||
self.__database.save( user, commit = False )
|
self.__database.save( user, commit = False )
|
||||||
|
|
||||||
# record the fact that the new user has access to their new notebook
|
# record the fact that the new user has access to their new notebook
|
||||||
self.__database.execute( user.sql_save_notebook( notebook_id, read_write = True, owner = True ), commit = False )
|
self.__database.execute( user.sql_save_notebook( notebook_id, read_write = True, owner = True, rank = 0 ), commit = False )
|
||||||
self.__database.execute( user.sql_save_notebook( trash_id, read_write = True, owner = True ), commit = False )
|
self.__database.execute( user.sql_save_notebook( trash_id, read_write = True, owner = True ), commit = False )
|
||||||
self.__database.commit()
|
self.__database.commit()
|
||||||
|
|
||||||
|
@ -966,7 +966,8 @@ class Users( object ):
|
||||||
|
|
||||||
# if the user doesn't already have access to this notebook, then grant access
|
# if the user doesn't already have access to this notebook, then grant access
|
||||||
if not self.__database.select_one( bool, user.sql_has_access( notebook.object_id ) ):
|
if not self.__database.select_one( bool, user.sql_has_access( notebook.object_id ) ):
|
||||||
self.__database.execute( user.sql_save_notebook( notebook.object_id, invite.read_write, invite.owner ), commit = False )
|
rank = self.__database.select_one( float, user.sql_highest_notebook_rank() ) + 1
|
||||||
|
self.__database.execute( user.sql_save_notebook( notebook.object_id, invite.read_write, invite.owner, rank = rank ), commit = False )
|
||||||
|
|
||||||
# the same goes for the trash notebook
|
# the same goes for the trash notebook
|
||||||
if not self.__database.select_one( bool, user.sql_has_access( notebook.trash_id ) ):
|
if not self.__database.select_one( bool, user.sql_has_access( notebook.trash_id ) ):
|
||||||
|
|
|
@ -41,14 +41,14 @@ class Test_controller( object ):
|
||||||
# SQL-returning methods in User, Note, and Notebook to return functions that manipulate data in
|
# SQL-returning methods in User, Note, and Notebook to return functions that manipulate data in
|
||||||
# Stub_database directly instead. This is all a little fragile, but it's better than relying on
|
# Stub_database directly instead. This is all a little fragile, but it's better than relying on
|
||||||
# the presence of a real database for unit tests.
|
# the presence of a real database for unit tests.
|
||||||
def sql_save_notebook( self, notebook_id, read_write, owner, database ):
|
def sql_save_notebook( self, notebook_id, read_write, owner, rank, database ):
|
||||||
if self.object_id in database.user_notebook:
|
if self.object_id in database.user_notebook:
|
||||||
database.user_notebook[ self.object_id ].append( ( notebook_id, read_write, owner ) )
|
database.user_notebook[ self.object_id ].append( ( notebook_id, read_write, owner, rank ) )
|
||||||
else:
|
else:
|
||||||
database.user_notebook[ self.object_id ] = [ ( notebook_id, read_write, owner ) ]
|
database.user_notebook[ self.object_id ] = [ ( notebook_id, read_write, owner, rank ) ]
|
||||||
|
|
||||||
User.sql_save_notebook = lambda self, notebook_id, read_write = False, owner = False: \
|
User.sql_save_notebook = lambda self, notebook_id, read_write = False, owner = False, rank = None: \
|
||||||
lambda database: sql_save_notebook( self, notebook_id, read_write, owner, database )
|
lambda database: sql_save_notebook( self, notebook_id, read_write, owner, rank, database )
|
||||||
|
|
||||||
def sql_remove_notebook( self, notebook_id, database ):
|
def sql_remove_notebook( self, notebook_id, database ):
|
||||||
if self.object_id in database.user_notebook:
|
if self.object_id in database.user_notebook:
|
||||||
|
@ -66,10 +66,11 @@ class Test_controller( object ):
|
||||||
if not notebook_infos: return []
|
if not notebook_infos: return []
|
||||||
|
|
||||||
for notebook_info in notebook_infos:
|
for notebook_info in notebook_infos:
|
||||||
( notebook_id, notebook_read_write, owner ) = notebook_info
|
( notebook_id, notebook_read_write, owner, rank ) = notebook_info
|
||||||
notebook = database.objects.get( notebook_id )[ -1 ]
|
notebook = database.objects.get( notebook_id )[ -1 ]
|
||||||
notebook.read_write = notebook_read_write
|
notebook.read_write = notebook_read_write
|
||||||
notebook.owner = owner
|
notebook.owner = owner
|
||||||
|
notebook.rank = rank
|
||||||
if parents_only and notebook.trash_id is None:
|
if parents_only and notebook.trash_id is None:
|
||||||
continue
|
continue
|
||||||
if undeleted_only and notebook.deleted is True:
|
if undeleted_only and notebook.deleted is True:
|
||||||
|
@ -118,7 +119,7 @@ class Test_controller( object ):
|
||||||
def sql_has_access( self, notebook_id, read_write, owner, database ):
|
def sql_has_access( self, notebook_id, read_write, owner, database ):
|
||||||
for ( user_id, notebook_infos ) in database.user_notebook.items():
|
for ( user_id, notebook_infos ) in database.user_notebook.items():
|
||||||
for notebook_info in notebook_infos:
|
for notebook_info in notebook_infos:
|
||||||
( db_notebook_id, db_read_write, db_owner ) = notebook_info
|
( db_notebook_id, db_read_write, db_owner, rank ) = notebook_info
|
||||||
|
|
||||||
if self.object_id == user_id and notebook_id == db_notebook_id:
|
if self.object_id == user_id and notebook_id == db_notebook_id:
|
||||||
if read_write is True and db_read_write is False:
|
if read_write is True and db_read_write is False:
|
||||||
|
@ -135,23 +136,53 @@ class Test_controller( object ):
|
||||||
def sql_update_access( self, notebook_id, read_write, owner, database ):
|
def sql_update_access( self, notebook_id, read_write, owner, database ):
|
||||||
for ( user_id, notebook_infos ) in database.user_notebook.items():
|
for ( user_id, notebook_infos ) in database.user_notebook.items():
|
||||||
for notebook_info in notebook_infos:
|
for notebook_info in notebook_infos:
|
||||||
( db_notebook_id, db_read_write, db_owner ) = notebook_info
|
( db_notebook_id, db_read_write, db_owner, rank ) = notebook_info
|
||||||
|
|
||||||
if self.object_id == user_id and notebook_id == db_notebook_id:
|
if self.object_id == user_id and notebook_id == db_notebook_id:
|
||||||
notebook_infos_copy = list( notebook_infos )
|
notebook_infos_copy = list( notebook_infos )
|
||||||
notebook_infos_copy.remove( notebook_info )
|
notebook_infos_copy.remove( notebook_info )
|
||||||
notebook_infos_copy.append( ( notebook_id, read_write, owner ) )
|
notebook_infos_copy.append( ( notebook_id, read_write, owner, rank ) )
|
||||||
database.user_notebook[ user_id ] = notebook_infos_copy
|
database.user_notebook[ user_id ] = notebook_infos_copy
|
||||||
|
|
||||||
User.sql_update_access = lambda self, notebook_id, read_write = False, owner = False: \
|
User.sql_update_access = lambda self, notebook_id, read_write = False, owner = False: \
|
||||||
lambda database: sql_update_access( self, notebook_id, read_write, owner, database )
|
lambda database: sql_update_access( self, notebook_id, read_write, owner, database )
|
||||||
|
|
||||||
|
def sql_update_notebook_rank( self, notebook_id, rank, database ):
|
||||||
|
max_rank = -1
|
||||||
|
|
||||||
|
for ( user_id, notebook_infos ) in database.user_notebook.items():
|
||||||
|
for notebook_info in notebook_infos:
|
||||||
|
( db_notebook_id, db_read_write, db_owner, db_rank ) = notebook_info
|
||||||
|
|
||||||
|
if self.object_id == user_id and notebook_id == db_notebook_id:
|
||||||
|
notebook_infos_copy = list( notebook_infos )
|
||||||
|
notebook_infos_copy.remove( notebook_info )
|
||||||
|
notebook_infos_copy.append( ( db_notebook_id, db_read_write, db_owner, rank ) )
|
||||||
|
database.user_notebook[ user_id ] = notebook_infos_copy
|
||||||
|
|
||||||
|
User.sql_update_notebook_rank = lambda self, notebook_id, rank: \
|
||||||
|
lambda database: sql_update_notebook_rank( self, notebook_id, rank, database )
|
||||||
|
|
||||||
|
def sql_highest_notebook_rank( self, database ):
|
||||||
|
max_rank = -1
|
||||||
|
|
||||||
|
for ( user_id, notebook_infos ) in database.user_notebook.items():
|
||||||
|
for notebook_info in notebook_infos:
|
||||||
|
( db_notebook_id, db_read_write, db_owner, db_rank ) = notebook_info
|
||||||
|
if self.object_id == user_id and db_rank > max_rank:
|
||||||
|
max_rank = db_rank
|
||||||
|
|
||||||
|
return max_rank
|
||||||
|
|
||||||
|
User.sql_highest_notebook_rank = lambda self: \
|
||||||
|
lambda database: sql_highest_notebook_rank( self, database )
|
||||||
|
|
||||||
def sql_revoke_invite_access( notebook_id, trash_id, email_address, database ):
|
def sql_revoke_invite_access( notebook_id, trash_id, email_address, database ):
|
||||||
invites = []
|
invites = []
|
||||||
|
|
||||||
for ( user_id, notebook_infos ) in database.user_notebook.items():
|
for ( user_id, notebook_infos ) in database.user_notebook.items():
|
||||||
for notebook_info in list( notebook_infos ):
|
for notebook_info in list( notebook_infos ):
|
||||||
( db_notebook_id, read_write, owner ) = notebook_info
|
( db_notebook_id, read_write, owner, rank ) = notebook_info
|
||||||
if db_notebook_id not in ( notebook_id, trash_id ): continue
|
if db_notebook_id not in ( notebook_id, trash_id ): continue
|
||||||
for ( object_id, obj_list ) in database.objects.items():
|
for ( object_id, obj_list ) in database.objects.items():
|
||||||
obj = obj_list[ -1 ]
|
obj = obj_list[ -1 ]
|
||||||
|
@ -255,7 +286,7 @@ class Test_controller( object ):
|
||||||
Notebook.sql_search_notes = lambda self, search_text: \
|
Notebook.sql_search_notes = lambda self, search_text: \
|
||||||
lambda database: sql_search_notes( self, search_text, database )
|
lambda database: sql_search_notes( self, search_text, database )
|
||||||
|
|
||||||
def sql_highest_rank( self, database ):
|
def sql_highest_note_rank( self, database ):
|
||||||
max_rank = -1
|
max_rank = -1
|
||||||
|
|
||||||
for ( object_id, obj_list ) in database.objects.items():
|
for ( object_id, obj_list ) in database.objects.items():
|
||||||
|
@ -265,8 +296,8 @@ class Test_controller( object ):
|
||||||
|
|
||||||
return max_rank
|
return max_rank
|
||||||
|
|
||||||
Notebook.sql_highest_rank = lambda self: \
|
Notebook.sql_highest_note_rank = lambda self: \
|
||||||
lambda database: sql_highest_rank( self, database )
|
lambda database: sql_highest_note_rank( self, database )
|
||||||
|
|
||||||
def sql_count_notes( self, database ):
|
def sql_count_notes( self, database ):
|
||||||
count = 0
|
count = 0
|
||||||
|
|
|
@ -54,12 +54,12 @@ class Test_notebooks( Test_controller ):
|
||||||
self.anon_notebook = Notebook.create( self.database.next_id( Notebook ), u"anon_notebook", user_id = user_id )
|
self.anon_notebook = Notebook.create( self.database.next_id( Notebook ), u"anon_notebook", user_id = user_id )
|
||||||
self.database.save( self.anon_notebook, commit = False )
|
self.database.save( self.anon_notebook, commit = False )
|
||||||
|
|
||||||
self.database.execute( self.user.sql_save_notebook( self.notebook.object_id, read_write = True, owner = True ) )
|
self.database.execute( self.user.sql_save_notebook( self.notebook.object_id, read_write = True, owner = True, rank = 0 ) )
|
||||||
self.database.execute( self.user.sql_save_notebook( self.notebook.trash_id, read_write = True, owner = True ) )
|
self.database.execute( self.user.sql_save_notebook( self.notebook.trash_id, read_write = True, owner = True, rank = 0 ) )
|
||||||
self.database.execute( self.user.sql_save_notebook( self.anon_notebook.object_id, read_write = False, owner = False ) )
|
self.database.execute( self.user.sql_save_notebook( self.anon_notebook.object_id, read_write = False, owner = False ) )
|
||||||
|
|
||||||
self.database.execute( self.user2.sql_save_notebook( self.notebook.object_id, read_write = True, owner = False ) )
|
self.database.execute( self.user2.sql_save_notebook( self.notebook.object_id, read_write = True, owner = False, rank = 0 ) )
|
||||||
self.database.execute( self.user2.sql_save_notebook( self.notebook.trash_id, read_write = True, owner = False ) )
|
self.database.execute( self.user2.sql_save_notebook( self.notebook.trash_id, read_write = True, owner = False, rank = 0 ) )
|
||||||
|
|
||||||
def make_users( self ):
|
def make_users( self ):
|
||||||
self.user = User.create( self.database.next_id( User ), self.username, self.password, self.email_address )
|
self.user = User.create( self.database.next_id( User ), self.username, self.password, self.email_address )
|
||||||
|
@ -2299,6 +2299,11 @@ class Test_notebooks( Test_controller ):
|
||||||
assert notebook.owner == True
|
assert notebook.owner == True
|
||||||
assert notebook.trash_id
|
assert notebook.trash_id
|
||||||
|
|
||||||
|
self.user.sql_load_notebooks()
|
||||||
|
notebooks = self.database.select_many( Notebook, self.user.sql_load_notebooks() )
|
||||||
|
new_notebook = [ notebook for notebook in notebooks if notebook.object_id == new_notebook_id ][ 0 ]
|
||||||
|
assert new_notebook.rank == 1
|
||||||
|
|
||||||
def test_contents_after_create( self ):
|
def test_contents_after_create( self ):
|
||||||
self.login()
|
self.login()
|
||||||
|
|
||||||
|
@ -2423,8 +2428,8 @@ class Test_notebooks( Test_controller ):
|
||||||
self.database.save( trash, commit = False )
|
self.database.save( trash, commit = False )
|
||||||
notebook = Notebook.create( self.database.next_id( Notebook ), u"notebook", trash.object_id )
|
notebook = Notebook.create( self.database.next_id( Notebook ), u"notebook", trash.object_id )
|
||||||
self.database.save( notebook, commit = False )
|
self.database.save( notebook, commit = False )
|
||||||
self.database.execute( self.user.sql_save_notebook( notebook.object_id, read_write = True, owner = True ) )
|
self.database.execute( self.user.sql_save_notebook( notebook.object_id, read_write = True, owner = True, rank = 1 ) )
|
||||||
self.database.execute( self.user.sql_save_notebook( notebook.trash_id, read_write = True, owner = True ) )
|
self.database.execute( self.user.sql_save_notebook( notebook.trash_id, read_write = True, owner = True, rank = 1 ) )
|
||||||
self.database.commit()
|
self.database.commit()
|
||||||
|
|
||||||
self.login()
|
self.login()
|
||||||
|
@ -2447,8 +2452,8 @@ class Test_notebooks( Test_controller ):
|
||||||
self.database.save( trash, commit = False )
|
self.database.save( trash, commit = False )
|
||||||
notebook = Notebook.create( self.database.next_id( Notebook ), u"notebook", trash.object_id )
|
notebook = Notebook.create( self.database.next_id( Notebook ), u"notebook", trash.object_id )
|
||||||
self.database.save( notebook, commit = False )
|
self.database.save( notebook, commit = False )
|
||||||
self.database.execute( self.user.sql_save_notebook( notebook.object_id, read_write = False, owner = False ) )
|
self.database.execute( self.user.sql_save_notebook( notebook.object_id, read_write = False, owner = False, rank = 1 ) )
|
||||||
self.database.execute( self.user.sql_save_notebook( notebook.trash_id, read_write = False, owner = False ) )
|
self.database.execute( self.user.sql_save_notebook( notebook.trash_id, read_write = False, owner = False, rank = 1 ) )
|
||||||
self.database.commit()
|
self.database.commit()
|
||||||
|
|
||||||
self.login()
|
self.login()
|
||||||
|
|
|
@ -68,9 +68,9 @@ class Test_users( Test_controller ):
|
||||||
|
|
||||||
self.user = User.create( self.database.next_id( User ), self.username, self.password, self.email_address )
|
self.user = User.create( self.database.next_id( User ), self.username, self.password, self.email_address )
|
||||||
self.database.save( self.user, commit = False )
|
self.database.save( self.user, commit = False )
|
||||||
self.database.execute( self.user.sql_save_notebook( notebook_id1, read_write = True, owner = True ), commit = False )
|
self.database.execute( self.user.sql_save_notebook( notebook_id1, read_write = True, owner = True, rank = 0 ), commit = False )
|
||||||
self.database.execute( self.user.sql_save_notebook( trash_id1, read_write = True, owner = True ), commit = False )
|
self.database.execute( self.user.sql_save_notebook( trash_id1, read_write = True, owner = True ), commit = False )
|
||||||
self.database.execute( self.user.sql_save_notebook( notebook_id2, read_write = True, owner = True ), commit = False )
|
self.database.execute( self.user.sql_save_notebook( notebook_id2, read_write = True, owner = True, rank = 1 ), commit = False )
|
||||||
self.database.execute( self.user.sql_save_notebook( trash_id2, read_write = True, owner = True ), commit = False )
|
self.database.execute( self.user.sql_save_notebook( trash_id2, read_write = True, owner = True ), commit = False )
|
||||||
|
|
||||||
self.user2 = User.create( self.database.next_id( User ), self.username2, self.password2, self.email_address2 )
|
self.user2 = User.create( self.database.next_id( User ), self.username2, self.password2, self.email_address2 )
|
||||||
|
@ -143,6 +143,7 @@ class Test_users( Test_controller ):
|
||||||
assert notebook.trash_id
|
assert notebook.trash_id
|
||||||
assert notebook.read_write == True
|
assert notebook.read_write == True
|
||||||
assert notebook.owner == True
|
assert notebook.owner == True
|
||||||
|
assert notebook.rank == 0
|
||||||
|
|
||||||
notebook = notebooks[ 1 ]
|
notebook = notebooks[ 1 ]
|
||||||
assert notebook.object_id == notebooks[ 0 ].trash_id
|
assert notebook.object_id == notebooks[ 0 ].trash_id
|
||||||
|
@ -151,6 +152,7 @@ class Test_users( Test_controller ):
|
||||||
assert notebook.trash_id == None
|
assert notebook.trash_id == None
|
||||||
assert notebook.read_write == True
|
assert notebook.read_write == True
|
||||||
assert notebook.owner == True
|
assert notebook.owner == True
|
||||||
|
assert notebook.rank == None
|
||||||
|
|
||||||
notebook = notebooks[ 2 ]
|
notebook = notebooks[ 2 ]
|
||||||
assert notebook.object_id == self.anon_notebook.object_id
|
assert notebook.object_id == self.anon_notebook.object_id
|
||||||
|
@ -159,6 +161,7 @@ class Test_users( Test_controller ):
|
||||||
assert notebook.trash_id == None
|
assert notebook.trash_id == None
|
||||||
assert notebook.read_write == False
|
assert notebook.read_write == False
|
||||||
assert notebook.owner == False
|
assert notebook.owner == False
|
||||||
|
assert notebook.rank == None
|
||||||
|
|
||||||
assert result.get( u"login_url" ) is None
|
assert result.get( u"login_url" ) is None
|
||||||
assert result[ u"logout_url" ] == self.settings[ u"global" ][ u"luminotes.https_url" ] + u"/users/logout"
|
assert result[ u"logout_url" ] == self.settings[ u"global" ][ u"luminotes.https_url" ] + u"/users/logout"
|
||||||
|
@ -222,6 +225,7 @@ class Test_users( Test_controller ):
|
||||||
assert notebook.trash_id
|
assert notebook.trash_id
|
||||||
assert notebook.read_write == False
|
assert notebook.read_write == False
|
||||||
assert notebook.owner == False
|
assert notebook.owner == False
|
||||||
|
assert notebook.rank == 1
|
||||||
|
|
||||||
notebook = notebooks.get( self.notebooks[ 0 ].trash_id )
|
notebook = notebooks.get( self.notebooks[ 0 ].trash_id )
|
||||||
assert notebook.revision
|
assert notebook.revision
|
||||||
|
@ -229,6 +233,7 @@ class Test_users( Test_controller ):
|
||||||
assert notebook.trash_id == None
|
assert notebook.trash_id == None
|
||||||
assert notebook.read_write == False
|
assert notebook.read_write == False
|
||||||
assert notebook.owner == False
|
assert notebook.owner == False
|
||||||
|
assert notebook.rank == None
|
||||||
|
|
||||||
notebook = notebooks.get( self.anon_notebook.object_id )
|
notebook = notebooks.get( self.anon_notebook.object_id )
|
||||||
assert notebook.revision == self.anon_notebook.revision
|
assert notebook.revision == self.anon_notebook.revision
|
||||||
|
@ -236,6 +241,7 @@ class Test_users( Test_controller ):
|
||||||
assert notebook.trash_id == None
|
assert notebook.trash_id == None
|
||||||
assert notebook.read_write == False
|
assert notebook.read_write == False
|
||||||
assert notebook.owner == False
|
assert notebook.owner == False
|
||||||
|
assert notebook.rank == None
|
||||||
|
|
||||||
assert result.get( u"login_url" ) is None
|
assert result.get( u"login_url" ) is None
|
||||||
assert result[ u"logout_url" ] == self.settings[ u"global" ][ u"luminotes.https_url" ] + u"/users/logout"
|
assert result[ u"logout_url" ] == self.settings[ u"global" ][ u"luminotes.https_url" ] + u"/users/logout"
|
||||||
|
@ -283,6 +289,7 @@ class Test_users( Test_controller ):
|
||||||
assert notebook.trash_id
|
assert notebook.trash_id
|
||||||
assert notebook.read_write == True
|
assert notebook.read_write == True
|
||||||
assert notebook.owner == True
|
assert notebook.owner == True
|
||||||
|
assert notebook.rank == 0
|
||||||
|
|
||||||
notebook = notebooks[ 1 ]
|
notebook = notebooks[ 1 ]
|
||||||
assert notebook.object_id == notebooks[ 0 ].trash_id
|
assert notebook.object_id == notebooks[ 0 ].trash_id
|
||||||
|
@ -291,6 +298,7 @@ class Test_users( Test_controller ):
|
||||||
assert notebook.trash_id == None
|
assert notebook.trash_id == None
|
||||||
assert notebook.read_write == True
|
assert notebook.read_write == True
|
||||||
assert notebook.owner == True
|
assert notebook.owner == True
|
||||||
|
assert notebook.rank == None
|
||||||
|
|
||||||
notebook = notebooks[ 2 ]
|
notebook = notebooks[ 2 ]
|
||||||
assert notebook.object_id == self.anon_notebook.object_id
|
assert notebook.object_id == self.anon_notebook.object_id
|
||||||
|
@ -299,6 +307,7 @@ class Test_users( Test_controller ):
|
||||||
assert notebook.trash_id == None
|
assert notebook.trash_id == None
|
||||||
assert notebook.read_write == False
|
assert notebook.read_write == False
|
||||||
assert notebook.owner == False
|
assert notebook.owner == False
|
||||||
|
assert notebook.rank == None
|
||||||
|
|
||||||
assert result.get( u"login_url" ) is None
|
assert result.get( u"login_url" ) is None
|
||||||
assert result[ u"logout_url" ] == self.settings[ u"global" ][ u"luminotes.https_url" ] + u"/users/logout"
|
assert result[ u"logout_url" ] == self.settings[ u"global" ][ u"luminotes.https_url" ] + u"/users/logout"
|
||||||
|
@ -379,22 +388,27 @@ class Test_users( Test_controller ):
|
||||||
assert result[ u"notebooks" ][ 0 ].name == self.notebooks[ 0 ].name
|
assert result[ u"notebooks" ][ 0 ].name == self.notebooks[ 0 ].name
|
||||||
assert result[ u"notebooks" ][ 0 ].read_write == True
|
assert result[ u"notebooks" ][ 0 ].read_write == True
|
||||||
assert result[ u"notebooks" ][ 0 ].owner == True
|
assert result[ u"notebooks" ][ 0 ].owner == True
|
||||||
|
assert result[ u"notebooks" ][ 0 ].rank == 0
|
||||||
assert result[ u"notebooks" ][ 1 ].object_id
|
assert result[ u"notebooks" ][ 1 ].object_id
|
||||||
assert result[ u"notebooks" ][ 1 ].name == u"trash"
|
assert result[ u"notebooks" ][ 1 ].name == u"trash"
|
||||||
assert result[ u"notebooks" ][ 1 ].read_write == True
|
assert result[ u"notebooks" ][ 1 ].read_write == True
|
||||||
assert result[ u"notebooks" ][ 1 ].owner == True
|
assert result[ u"notebooks" ][ 1 ].owner == True
|
||||||
|
assert result[ u"notebooks" ][ 1 ].rank == None
|
||||||
assert result[ u"notebooks" ][ 2 ].object_id == self.notebooks[ 1 ].object_id
|
assert result[ u"notebooks" ][ 2 ].object_id == self.notebooks[ 1 ].object_id
|
||||||
assert result[ u"notebooks" ][ 2 ].name == self.notebooks[ 1 ].name
|
assert result[ u"notebooks" ][ 2 ].name == self.notebooks[ 1 ].name
|
||||||
assert result[ u"notebooks" ][ 2 ].read_write == True
|
assert result[ u"notebooks" ][ 2 ].read_write == True
|
||||||
assert result[ u"notebooks" ][ 2 ].owner == True
|
assert result[ u"notebooks" ][ 2 ].owner == True
|
||||||
|
assert result[ u"notebooks" ][ 2 ].rank == 1
|
||||||
assert result[ u"notebooks" ][ 3 ].object_id
|
assert result[ u"notebooks" ][ 3 ].object_id
|
||||||
assert result[ u"notebooks" ][ 3 ].name == u"trash"
|
assert result[ u"notebooks" ][ 3 ].name == u"trash"
|
||||||
assert result[ u"notebooks" ][ 3 ].read_write == True
|
assert result[ u"notebooks" ][ 3 ].read_write == True
|
||||||
assert result[ u"notebooks" ][ 3 ].owner == True
|
assert result[ u"notebooks" ][ 3 ].owner == True
|
||||||
|
assert result[ u"notebooks" ][ 3 ].rank == None
|
||||||
assert result[ u"notebooks" ][ 4 ].object_id == self.anon_notebook.object_id
|
assert result[ u"notebooks" ][ 4 ].object_id == self.anon_notebook.object_id
|
||||||
assert result[ u"notebooks" ][ 4 ].name == self.anon_notebook.name
|
assert result[ u"notebooks" ][ 4 ].name == self.anon_notebook.name
|
||||||
assert result[ u"notebooks" ][ 4 ].read_write == False
|
assert result[ u"notebooks" ][ 4 ].read_write == False
|
||||||
assert result[ u"notebooks" ][ 4 ].owner == False
|
assert result[ u"notebooks" ][ 4 ].owner == False
|
||||||
|
assert result[ u"notebooks" ][ 4 ].rank == None
|
||||||
assert result[ u"login_url" ] is None
|
assert result[ u"login_url" ] is None
|
||||||
assert result[ u"logout_url" ] == self.settings[ u"global" ][ u"luminotes.https_url" ] + u"/users/logout"
|
assert result[ u"logout_url" ] == self.settings[ u"global" ][ u"luminotes.https_url" ] + u"/users/logout"
|
||||||
|
|
||||||
|
@ -412,6 +426,7 @@ class Test_users( Test_controller ):
|
||||||
assert result[ u"notebooks" ][ 0 ].name == self.anon_notebook.name
|
assert result[ u"notebooks" ][ 0 ].name == self.anon_notebook.name
|
||||||
assert result[ u"notebooks" ][ 0 ].read_write == False
|
assert result[ u"notebooks" ][ 0 ].read_write == False
|
||||||
assert result[ u"notebooks" ][ 0 ].owner == False
|
assert result[ u"notebooks" ][ 0 ].owner == False
|
||||||
|
assert result[ u"notebooks" ][ 0 ].rank == None
|
||||||
|
|
||||||
login_note = self.database.select_one( Note, self.anon_notebook.sql_load_note_by_title( u"login" ) )
|
login_note = self.database.select_one( Note, self.anon_notebook.sql_load_note_by_title( u"login" ) )
|
||||||
assert result[ u"login_url" ] == u"%s/notebooks/%s?note_id=%s" % (
|
assert result[ u"login_url" ] == u"%s/notebooks/%s?note_id=%s" % (
|
||||||
|
@ -426,7 +441,7 @@ class Test_users( Test_controller ):
|
||||||
assert rate_plan[ u"name" ] == u"super"
|
assert rate_plan[ u"name" ] == u"super"
|
||||||
assert rate_plan[ u"storage_quota_bytes" ] == 1337 * 10
|
assert rate_plan[ u"storage_quota_bytes" ] == 1337 * 10
|
||||||
|
|
||||||
def test_current_after_login_with_invite_id( self ):
|
def test_login_with_invite_id( self ):
|
||||||
# trick send_invites() into using a fake SMTP server
|
# trick send_invites() into using a fake SMTP server
|
||||||
Stub_smtp.reset()
|
Stub_smtp.reset()
|
||||||
smtplib.SMTP = Stub_smtp
|
smtplib.SMTP = Stub_smtp
|
||||||
|
@ -461,7 +476,7 @@ class Test_users( Test_controller ):
|
||||||
assert cherrypy.root.users.check_access( self.user2.object_id, self.notebooks[ 0 ].object_id )
|
assert cherrypy.root.users.check_access( self.user2.object_id, self.notebooks[ 0 ].object_id )
|
||||||
assert cherrypy.root.users.check_access( self.user2.object_id, self.notebooks[ 0 ].trash_id )
|
assert cherrypy.root.users.check_access( self.user2.object_id, self.notebooks[ 0 ].trash_id )
|
||||||
|
|
||||||
def test_current_after_login_with_after_login( self ):
|
def test_login_with_after_login( self ):
|
||||||
after_login = u"/foo/bar"
|
after_login = u"/foo/bar"
|
||||||
|
|
||||||
result = self.http_post( "/users/login", dict(
|
result = self.http_post( "/users/login", dict(
|
||||||
|
@ -473,7 +488,7 @@ class Test_users( Test_controller ):
|
||||||
|
|
||||||
assert result[ u"redirect" ] == after_login
|
assert result[ u"redirect" ] == after_login
|
||||||
|
|
||||||
def test_current_after_login_with_after_login_with_full_url( self ):
|
def test_login_with_after_login_with_full_url( self ):
|
||||||
after_login = u"http://this_url/does/not/start/with/a/slash"
|
after_login = u"http://this_url/does/not/start/with/a/slash"
|
||||||
|
|
||||||
result = self.http_post( "/users/login", dict(
|
result = self.http_post( "/users/login", dict(
|
||||||
|
@ -601,6 +616,7 @@ class Test_users( Test_controller ):
|
||||||
assert result[ u"notebooks" ][ 0 ].name == self.anon_notebook.name
|
assert result[ u"notebooks" ][ 0 ].name == self.anon_notebook.name
|
||||||
assert result[ u"notebooks" ][ 0 ].read_write == False
|
assert result[ u"notebooks" ][ 0 ].read_write == False
|
||||||
assert result[ u"notebooks" ][ 0 ].owner == False
|
assert result[ u"notebooks" ][ 0 ].owner == False
|
||||||
|
assert result[ u"notebooks" ][ 0 ].rank == None
|
||||||
|
|
||||||
login_note = self.database.select_one( Note, self.anon_notebook.sql_load_note_by_title( u"login" ) )
|
login_note = self.database.select_one( Note, self.anon_notebook.sql_load_note_by_title( u"login" ) )
|
||||||
assert result[ u"login_url" ] == u"%s/notebooks/%s?note_id=%s" % (
|
assert result[ u"login_url" ] == u"%s/notebooks/%s?note_id=%s" % (
|
||||||
|
@ -2104,6 +2120,9 @@ class Test_users( Test_controller ):
|
||||||
assert result[ u"error" ]
|
assert result[ u"error" ]
|
||||||
|
|
||||||
def test_convert_invite_to_access( self ):
|
def test_convert_invite_to_access( self ):
|
||||||
|
# start the invitee out with access to one notebook
|
||||||
|
self.database.execute( self.user2.sql_save_notebook( self.notebooks[ 1 ].object_id, read_write = True, owner = False, rank = 7 ), commit = False )
|
||||||
|
|
||||||
# trick send_invites() into using a fake SMTP server
|
# trick send_invites() into using a fake SMTP server
|
||||||
Stub_smtp.reset()
|
Stub_smtp.reset()
|
||||||
smtplib.SMTP = Stub_smtp
|
smtplib.SMTP = Stub_smtp
|
||||||
|
@ -2144,6 +2163,12 @@ class Test_users( Test_controller ):
|
||||||
) )
|
) )
|
||||||
assert access is True
|
assert access is True
|
||||||
|
|
||||||
|
self.user.sql_load_notebooks()
|
||||||
|
notebooks = self.database.select_many( Notebook, self.user2.sql_load_notebooks() )
|
||||||
|
new_notebook = [ notebook for notebook in notebooks if notebook.object_id == invite.notebook_id ][ 0 ]
|
||||||
|
print new_notebook.rank
|
||||||
|
assert new_notebook.rank == 8 # one higher than the other notebook this user has access to
|
||||||
|
|
||||||
assert invite.redeemed_user_id == self.user2.object_id
|
assert invite.redeemed_user_id == self.user2.object_id
|
||||||
|
|
||||||
def test_convert_invite_to_access_same_user( self ):
|
def test_convert_invite_to_access_same_user( self ):
|
||||||
|
@ -3245,6 +3270,7 @@ class Test_users( Test_controller ):
|
||||||
assert result[ u"notebooks" ][ 0 ].name == self.notebooks[ 0 ].name
|
assert result[ u"notebooks" ][ 0 ].name == self.notebooks[ 0 ].name
|
||||||
assert result[ u"notebooks" ][ 0 ].read_write == True
|
assert result[ u"notebooks" ][ 0 ].read_write == True
|
||||||
assert result[ u"notebooks" ][ 0 ].owner == True
|
assert result[ u"notebooks" ][ 0 ].owner == True
|
||||||
|
assert result[ u"notebooks" ][ 0 ].rank == 0
|
||||||
|
|
||||||
assert result[ u"login_url" ] == None
|
assert result[ u"login_url" ] == None
|
||||||
assert result[ u"logout_url" ] == self.settings[ u"global" ][ u"luminotes.https_url" ] + u"/users/logout"
|
assert result[ u"logout_url" ] == self.settings[ u"global" ][ u"luminotes.https_url" ] + u"/users/logout"
|
||||||
|
@ -3284,6 +3310,7 @@ class Test_users( Test_controller ):
|
||||||
assert result[ u"notebooks" ][ 0 ].name == self.notebooks[ 0 ].name
|
assert result[ u"notebooks" ][ 0 ].name == self.notebooks[ 0 ].name
|
||||||
assert result[ u"notebooks" ][ 0 ].read_write == True
|
assert result[ u"notebooks" ][ 0 ].read_write == True
|
||||||
assert result[ u"notebooks" ][ 0 ].owner == True
|
assert result[ u"notebooks" ][ 0 ].owner == True
|
||||||
|
assert result[ u"notebooks" ][ 0 ].rank == 0
|
||||||
|
|
||||||
assert result[ u"login_url" ] == None
|
assert result[ u"login_url" ] == None
|
||||||
assert result[ u"logout_url" ] == self.settings[ u"global" ][ u"luminotes.https_url" ] + u"/users/logout"
|
assert result[ u"logout_url" ] == self.settings[ u"global" ][ u"luminotes.https_url" ] + u"/users/logout"
|
||||||
|
@ -3322,6 +3349,7 @@ class Test_users( Test_controller ):
|
||||||
assert result[ u"notebooks" ][ 0 ].name == self.notebooks[ 0 ].name
|
assert result[ u"notebooks" ][ 0 ].name == self.notebooks[ 0 ].name
|
||||||
assert result[ u"notebooks" ][ 0 ].read_write == True
|
assert result[ u"notebooks" ][ 0 ].read_write == True
|
||||||
assert result[ u"notebooks" ][ 0 ].owner == True
|
assert result[ u"notebooks" ][ 0 ].owner == True
|
||||||
|
assert result[ u"notebooks" ][ 0 ].rank == 0
|
||||||
|
|
||||||
assert result[ u"login_url" ] == None
|
assert result[ u"login_url" ] == None
|
||||||
assert result[ u"logout_url" ] == self.settings[ u"global" ][ u"luminotes.https_url" ] + u"/users/logout"
|
assert result[ u"logout_url" ] == self.settings[ u"global" ][ u"luminotes.https_url" ] + u"/users/logout"
|
||||||
|
@ -3360,6 +3388,7 @@ class Test_users( Test_controller ):
|
||||||
assert result[ u"notebooks" ][ 0 ].name == self.notebooks[ 0 ].name
|
assert result[ u"notebooks" ][ 0 ].name == self.notebooks[ 0 ].name
|
||||||
assert result[ u"notebooks" ][ 0 ].read_write == True
|
assert result[ u"notebooks" ][ 0 ].read_write == True
|
||||||
assert result[ u"notebooks" ][ 0 ].owner == True
|
assert result[ u"notebooks" ][ 0 ].owner == True
|
||||||
|
assert result[ u"notebooks" ][ 0 ].rank == 0
|
||||||
|
|
||||||
assert result[ u"login_url" ] == None
|
assert result[ u"login_url" ] == None
|
||||||
assert result[ u"logout_url" ] == self.settings[ u"global" ][ u"luminotes.https_url" ] + u"/users/logout"
|
assert result[ u"logout_url" ] == self.settings[ u"global" ][ u"luminotes.https_url" ] + u"/users/logout"
|
||||||
|
@ -3396,6 +3425,7 @@ class Test_users( Test_controller ):
|
||||||
assert result[ u"notebooks" ][ 0 ].name == self.notebooks[ 0 ].name
|
assert result[ u"notebooks" ][ 0 ].name == self.notebooks[ 0 ].name
|
||||||
assert result[ u"notebooks" ][ 0 ].read_write == True
|
assert result[ u"notebooks" ][ 0 ].read_write == True
|
||||||
assert result[ u"notebooks" ][ 0 ].owner == True
|
assert result[ u"notebooks" ][ 0 ].owner == True
|
||||||
|
assert result[ u"notebooks" ][ 0 ].rank == 0
|
||||||
|
|
||||||
assert result[ u"login_url" ] == None
|
assert result[ u"login_url" ] == None
|
||||||
assert result[ u"logout_url" ] == self.settings[ u"global" ][ u"luminotes.https_url" ] + u"/users/logout"
|
assert result[ u"logout_url" ] == self.settings[ u"global" ][ u"luminotes.https_url" ] + u"/users/logout"
|
||||||
|
|
|
@ -12,7 +12,8 @@ class Notebook( Persistent ):
|
||||||
WHITESPACE_PATTERN = re.compile( r"\s+" )
|
WHITESPACE_PATTERN = re.compile( r"\s+" )
|
||||||
SEARCH_OPERATORS = re.compile( r"[&|!()'\\:]" )
|
SEARCH_OPERATORS = re.compile( r"[&|!()'\\:]" )
|
||||||
|
|
||||||
def __init__( self, object_id, revision = None, name = None, trash_id = None, deleted = False, user_id = None, read_write = True, owner = True ):
|
def __init__( self, object_id, revision = None, name = None, trash_id = None, deleted = False,
|
||||||
|
user_id = None, read_write = True, owner = True, rank = None ):
|
||||||
"""
|
"""
|
||||||
Create a new notebook with the given id and name.
|
Create a new notebook with the given id and name.
|
||||||
|
|
||||||
|
@ -32,6 +33,8 @@ class Notebook( Persistent ):
|
||||||
@param read_write: whether this view of the notebook is currently read-write (optional, defaults to True)
|
@param read_write: whether this view of the notebook is currently read-write (optional, defaults to True)
|
||||||
@type owner: bool or NoneType
|
@type owner: bool or NoneType
|
||||||
@param owner: whether this view of the notebook currently has owner-level access (optional, defaults to True)
|
@param owner: whether this view of the notebook currently has owner-level access (optional, defaults to True)
|
||||||
|
@type rank: float or NoneType
|
||||||
|
@param rank: indicates numeric ordering of this note in relation to other notebooks
|
||||||
@rtype: Notebook
|
@rtype: Notebook
|
||||||
@return: newly constructed notebook
|
@return: newly constructed notebook
|
||||||
"""
|
"""
|
||||||
|
@ -42,9 +45,10 @@ class Notebook( Persistent ):
|
||||||
self.__user_id = user_id
|
self.__user_id = user_id
|
||||||
self.__read_write = read_write
|
self.__read_write = read_write
|
||||||
self.__owner = owner
|
self.__owner = owner
|
||||||
|
self.__rank = rank
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create( object_id, name = None, trash_id = None, deleted = False, user_id = None, read_write = True, owner = True ):
|
def create( object_id, name = None, trash_id = None, deleted = False, user_id = None, read_write = True, owner = True, rank = None ):
|
||||||
"""
|
"""
|
||||||
Convenience constructor for creating a new notebook.
|
Convenience constructor for creating a new notebook.
|
||||||
|
|
||||||
|
@ -62,10 +66,12 @@ class Notebook( Persistent ):
|
||||||
@param read_write: whether this view of the notebook is currently read-write (optional, defaults to True)
|
@param read_write: whether this view of the notebook is currently read-write (optional, defaults to True)
|
||||||
@type owner: bool or NoneType
|
@type owner: bool or NoneType
|
||||||
@param owner: whether this view of the notebook currently has owner-level access (optional, defaults to True)
|
@param owner: whether this view of the notebook currently has owner-level access (optional, defaults to True)
|
||||||
|
@type rank: float or NoneType
|
||||||
|
@param rank: indicates numeric ordering of this note in relation to other notebooks
|
||||||
@rtype: Notebook
|
@rtype: Notebook
|
||||||
@return: newly constructed notebook
|
@return: newly constructed notebook
|
||||||
"""
|
"""
|
||||||
return Notebook( object_id, name = name, trash_id = trash_id, user_id = user_id, read_write = read_write, owner = owner )
|
return Notebook( object_id, name = name, trash_id = trash_id, user_id = user_id, read_write = read_write, owner = owner, rank = rank )
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def sql_load( object_id, revision = None ):
|
def sql_load( object_id, revision = None ):
|
||||||
|
@ -182,7 +188,7 @@ class Notebook( Persistent ):
|
||||||
) as sub;
|
) as sub;
|
||||||
""" % ( quote( search_text ), quote( self.object_id ) )
|
""" % ( quote( search_text ), quote( self.object_id ) )
|
||||||
|
|
||||||
def sql_highest_rank( self ):
|
def sql_highest_note_rank( self ):
|
||||||
"""
|
"""
|
||||||
Return a SQL string to determine the highest numbered rank of all notes in this notebook."
|
Return a SQL string to determine the highest numbered rank of all notes in this notebook."
|
||||||
"""
|
"""
|
||||||
|
@ -232,9 +238,15 @@ class Notebook( Persistent ):
|
||||||
self.__user_id = user_id
|
self.__user_id = user_id
|
||||||
self.update_revision()
|
self.update_revision()
|
||||||
|
|
||||||
|
def __set_rank( self, rank ):
|
||||||
|
# The rank member isn't actually saved to the database, so setting it doesn't need to
|
||||||
|
# call update_revision().
|
||||||
|
self.__rank = rank
|
||||||
|
|
||||||
name = property( lambda self: self.__name, __set_name )
|
name = property( lambda self: self.__name, __set_name )
|
||||||
trash_id = property( lambda self: self.__trash_id )
|
trash_id = property( lambda self: self.__trash_id )
|
||||||
read_write = property( lambda self: self.__read_write, __set_read_write )
|
read_write = property( lambda self: self.__read_write, __set_read_write )
|
||||||
owner = property( lambda self: self.__owner, __set_owner )
|
owner = property( lambda self: self.__owner, __set_owner )
|
||||||
deleted = property( lambda self: self.__deleted, __set_deleted )
|
deleted = property( lambda self: self.__deleted, __set_deleted )
|
||||||
user_id = property( lambda self: self.__user_id, __set_user_id )
|
user_id = property( lambda self: self.__user_id, __set_user_id )
|
||||||
|
rank = property( lambda self: self.__rank, __set_rank )
|
||||||
|
|
|
@ -149,18 +149,27 @@ class User( Persistent ):
|
||||||
read_write_clause = ""
|
read_write_clause = ""
|
||||||
|
|
||||||
return \
|
return \
|
||||||
"select notebook_current.*, user_notebook.read_write, user_notebook.owner from user_notebook, notebook_current " + \
|
"""
|
||||||
"where user_notebook.user_id = %s%s%s%s and user_notebook.notebook_id = notebook_current.id order by revision;" % \
|
select
|
||||||
( quote( self.object_id ), parents_only_clause, undeleted_only_clause, read_write_clause )
|
notebook_current.*, user_notebook.read_write, user_notebook.owner, user_notebook.rank
|
||||||
|
from
|
||||||
|
user_notebook, notebook_current
|
||||||
|
where
|
||||||
|
user_notebook.user_id = %s%s%s%s and
|
||||||
|
user_notebook.notebook_id = notebook_current.id
|
||||||
|
order by user_notebook.rank;
|
||||||
|
""" % ( quote( self.object_id ), parents_only_clause, undeleted_only_clause, read_write_clause )
|
||||||
|
|
||||||
def sql_save_notebook( self, notebook_id, read_write = True, owner = True ):
|
def sql_save_notebook( self, notebook_id, read_write = True, owner = True, rank = None ):
|
||||||
"""
|
"""
|
||||||
Return a SQL string to save the id of a notebook to which this user has access.
|
Return a SQL string to save the id of a notebook to which this user has access.
|
||||||
"""
|
"""
|
||||||
|
if rank is None: rank = quote( None )
|
||||||
|
|
||||||
return \
|
return \
|
||||||
"insert into user_notebook ( user_id, notebook_id, read_write, owner ) values " + \
|
"insert into user_notebook ( user_id, notebook_id, read_write, owner, rank ) values " + \
|
||||||
"( %s, %s, %s, %s );" % ( quote( self.object_id ), quote( notebook_id ), quote( read_write and 't' or 'f' ),
|
"( %s, %s, %s, %s );" % ( quote( self.object_id ), quote( notebook_id ), quote( read_write and 't' or 'f' ),
|
||||||
quote( owner and 't' or 'f' ) )
|
quote( owner and 't' or 'f' ), rank )
|
||||||
|
|
||||||
def sql_remove_notebook( self, notebook_id ):
|
def sql_remove_notebook( self, notebook_id ):
|
||||||
"""
|
"""
|
||||||
|
@ -199,6 +208,20 @@ class User( Persistent ):
|
||||||
( quote( read_write and 't' or 'f' ), quote( owner and 't' or 'f' ), quote( self.object_id ),
|
( quote( read_write and 't' or 'f' ), quote( owner and 't' or 'f' ), quote( self.object_id ),
|
||||||
quote( notebook_id ) )
|
quote( notebook_id ) )
|
||||||
|
|
||||||
|
def sql_update_notebook_rank( self, notebook_id, rank ):
|
||||||
|
"""
|
||||||
|
Return a SQL string to update the user's rank for the given notebook.
|
||||||
|
"""
|
||||||
|
return \
|
||||||
|
"update user_notebook set rank = %s where user_id = %s and notebook_id = %s;" % \
|
||||||
|
( quote( rank ), quote( self.object_id ), quote( notebook_id ) )
|
||||||
|
|
||||||
|
def sql_highest_notebook_rank( self ):
|
||||||
|
"""
|
||||||
|
Return a SQL string to determine the highest numbered rank of all notebooks the user has access to."
|
||||||
|
"""
|
||||||
|
return "select coalesce( max( rank ), -1 ) from user_notebook where user_id = %s;" % quote( self.object_id )
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def sql_revoke_invite_access( notebook_id, trash_id, email_address ):
|
def sql_revoke_invite_access( notebook_id, trash_id, email_address ):
|
||||||
return \
|
return \
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
alter table user_notebook add column rank numeric;
|
|
@ -165,7 +165,8 @@ CREATE TABLE user_notebook (
|
||||||
user_id text NOT NULL,
|
user_id text NOT NULL,
|
||||||
notebook_id text NOT NULL,
|
notebook_id text NOT NULL,
|
||||||
read_write boolean DEFAULT false,
|
read_write boolean DEFAULT false,
|
||||||
"owner" boolean DEFAULT false
|
"owner" boolean DEFAULT false,
|
||||||
|
rank numeric
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -12,9 +12,12 @@ class Test_notebook( object ):
|
||||||
self.trash_name = u"trash"
|
self.trash_name = u"trash"
|
||||||
self.user_id = u"me"
|
self.user_id = u"me"
|
||||||
self.delta = timedelta( seconds = 1 )
|
self.delta = timedelta( seconds = 1 )
|
||||||
|
self.read_write = True
|
||||||
|
self.owner = False
|
||||||
|
self.rank = 17.5
|
||||||
|
|
||||||
self.trash = Notebook.create( self.trash_id, self.trash_name, read_write = False, deleted = False, user_id = self.user_id )
|
self.trash = Notebook.create( self.trash_id, self.trash_name, read_write = False, deleted = False, user_id = self.user_id )
|
||||||
self.notebook = Notebook.create( self.object_id, self.name, trash_id = self.trash.object_id, deleted = False, user_id = self.user_id )
|
self.notebook = Notebook.create( self.object_id, self.name, trash_id = self.trash.object_id, deleted = False, user_id = self.user_id, read_write = self.read_write, owner = self.owner, rank = self.rank )
|
||||||
self.note = Note.create( "19", u"<h3>title</h3>blah" )
|
self.note = Note.create( "19", u"<h3>title</h3>blah" )
|
||||||
|
|
||||||
def test_create( self ):
|
def test_create( self ):
|
||||||
|
@ -25,6 +28,9 @@ class Test_notebook( object ):
|
||||||
assert self.notebook.trash_id == self.trash_id
|
assert self.notebook.trash_id == self.trash_id
|
||||||
assert self.notebook.deleted == False
|
assert self.notebook.deleted == False
|
||||||
assert self.notebook.user_id == self.user_id
|
assert self.notebook.user_id == self.user_id
|
||||||
|
assert self.notebook.read_write == self.read_write
|
||||||
|
assert self.notebook.owner == self.owner
|
||||||
|
assert self.notebook.rank == self.rank
|
||||||
|
|
||||||
assert self.trash.object_id == self.trash_id
|
assert self.trash.object_id == self.trash_id
|
||||||
assert datetime.now( tz = utc ) - self.trash.revision < self.delta
|
assert datetime.now( tz = utc ) - self.trash.revision < self.delta
|
||||||
|
@ -33,6 +39,9 @@ class Test_notebook( object ):
|
||||||
assert self.trash.trash_id == None
|
assert self.trash.trash_id == None
|
||||||
assert self.trash.deleted == False
|
assert self.trash.deleted == False
|
||||||
assert self.trash.user_id == self.user_id
|
assert self.trash.user_id == self.user_id
|
||||||
|
assert self.trash.read_write == False
|
||||||
|
assert self.trash.owner == True
|
||||||
|
assert self.trash.rank == None
|
||||||
|
|
||||||
def test_set_name( self ):
|
def test_set_name( self ):
|
||||||
new_name = u"my new notebook"
|
new_name = u"my new notebook"
|
||||||
|
@ -63,6 +72,13 @@ class Test_notebook( object ):
|
||||||
assert self.notebook.user_id == u"5"
|
assert self.notebook.user_id == u"5"
|
||||||
assert self.notebook.revision > previous_revision
|
assert self.notebook.revision > previous_revision
|
||||||
|
|
||||||
|
def test_set_rank( self ):
|
||||||
|
original_revision = self.notebook.revision
|
||||||
|
self.notebook.rank = 17.7
|
||||||
|
|
||||||
|
assert self.notebook.rank == 17.7
|
||||||
|
assert self.notebook.revision == original_revision
|
||||||
|
|
||||||
def test_to_dict( self ):
|
def test_to_dict( self ):
|
||||||
d = self.notebook.to_dict()
|
d = self.notebook.to_dict()
|
||||||
|
|
||||||
|
|
|
@ -221,6 +221,18 @@ img {
|
||||||
background-image: url(/static/images/numbered_list_button_down.png);
|
background-image: url(/static/images/numbered_list_button_down.png);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#current_notebook_up_hover_preload {
|
||||||
|
height: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
background-image: url(/static/images/arrow_up_hover.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
#current_notebook_down_hover_preload {
|
||||||
|
height: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
background-image: url(/static/images/arrow_down_hover.png);
|
||||||
|
}
|
||||||
|
|
||||||
#link_area {
|
#link_area {
|
||||||
float: right;
|
float: right;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
@ -564,6 +576,16 @@ img {
|
||||||
background: url(/static/images/current_notebook_inner_tl.png) no-repeat top left;
|
background: url(/static/images/current_notebook_inner_tl.png) no-repeat top left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#current_notebook_up {
|
||||||
|
cursor: pointer;
|
||||||
|
padding-top: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#current_notebook_down {
|
||||||
|
cursor: pointer;
|
||||||
|
padding-top: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
.trash_notebook_color {
|
.trash_notebook_color {
|
||||||
background-color: #d0d0d0;
|
background-color: #d0d0d0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
IMAGE_DIR = "/static/images/";
|
||||||
|
|
||||||
function Wiki( invoker ) {
|
function Wiki( invoker ) {
|
||||||
this.next_id = null;
|
this.next_id = null;
|
||||||
this.focused_editor = null;
|
this.focused_editor = null;
|
||||||
|
@ -105,9 +107,28 @@ function Wiki( invoker ) {
|
||||||
"href": "/notebooks/" + this.notebook.trash_id + "?parent_id=" + this.notebook.object_id
|
"href": "/notebooks/" + this.notebook.trash_id + "?parent_id=" + this.notebook.object_id
|
||||||
}, "trash" );
|
}, "trash" );
|
||||||
var message_div = this.display_message( "The notebook has been moved to the", [ trash_link, ". ", undo_button ], "notes_top" );
|
var message_div = this.display_message( "The notebook has been moved to the", [ trash_link, ". ", undo_button ], "notes_top" );
|
||||||
var self = this;
|
|
||||||
connect( undo_button, "onclick", function ( event ) { self.undelete_notebook( event, deleted_id ); } );
|
connect( undo_button, "onclick", function ( event ) { self.undelete_notebook( event, deleted_id ); } );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var current_notebook_up = getElement( "current_notebook_up" );
|
||||||
|
if ( current_notebook_up ) {
|
||||||
|
connect( current_notebook_up, "onmouseover", function ( event ) { current_notebook_up.src = IMAGE_DIR + "up_arrow_hover.png"; } );
|
||||||
|
connect( current_notebook_up, "onmouseout", function ( event ) { current_notebook_up.src = IMAGE_DIR + "up_arrow.png"; } );
|
||||||
|
connect( current_notebook_up, "onclick", function ( event ) {
|
||||||
|
current_notebook_up.src = IMAGE_DIR + "up_arrow.png";
|
||||||
|
self.move_current_notebook_up( event );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
var current_notebook_down = getElement( "current_notebook_down" );
|
||||||
|
if ( current_notebook_down ) {
|
||||||
|
connect( current_notebook_down, "onmouseover", function ( event ) { current_notebook_down.src = IMAGE_DIR + "down_arrow_hover.png"; } );
|
||||||
|
connect( current_notebook_down, "onmouseout", function ( event ) { current_notebook_down.src = IMAGE_DIR + "down_arrow.png"; } );
|
||||||
|
connect( current_notebook_down, "onclick", function ( event ) {
|
||||||
|
current_notebook_down.src = IMAGE_DIR + "down_arrow.png";
|
||||||
|
self.move_current_notebook_down( event );
|
||||||
|
} );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Wiki.prototype.update_next_id = function ( result ) {
|
Wiki.prototype.update_next_id = function ( result ) {
|
||||||
|
@ -851,8 +872,6 @@ Wiki.prototype.editor_key_pressed = function ( editor, event ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IMAGE_DIR = "/static/images/";
|
|
||||||
|
|
||||||
Wiki.prototype.make_image_button = function ( name, filename_prefix, handle_mouse_up_and_down ) {
|
Wiki.prototype.make_image_button = function ( name, filename_prefix, handle_mouse_up_and_down ) {
|
||||||
var button = getElement( name );
|
var button = getElement( name );
|
||||||
|
|
||||||
|
@ -1530,6 +1549,56 @@ Wiki.prototype.display_invites = function ( invite_area ) {
|
||||||
replaceChildNodes( invite_area, div );
|
replaceChildNodes( invite_area, div );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Wiki.prototype.move_current_notebook_up = function ( event ) {
|
||||||
|
var current_notebook = getElement( "current_notebook_wrapper" );
|
||||||
|
var sibling_notebook = current_notebook;
|
||||||
|
|
||||||
|
// find the previous sibling notebook node
|
||||||
|
do {
|
||||||
|
var sibling_notebook = sibling_notebook.previousSibling;
|
||||||
|
} while ( sibling_notebook && sibling_notebook.className != "link_area_item" );
|
||||||
|
|
||||||
|
removeElement( current_notebook );
|
||||||
|
if ( sibling_notebook )
|
||||||
|
// move the current notebook up before the previous notebook node
|
||||||
|
insertSiblingNodesBefore( sibling_notebook, current_notebook );
|
||||||
|
// if the current notebook is the first one, wrap it around to the bottom of the list
|
||||||
|
else {
|
||||||
|
var notebooks_area = getElement( "notebooks_area" );
|
||||||
|
appendChildNodes( notebooks_area, current_notebook );
|
||||||
|
}
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
this.invoker.invoke( "/notebooks/move_up", "POST", {
|
||||||
|
"notebook_id": this.notebook_id
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
Wiki.prototype.move_current_notebook_down = function ( event ) {
|
||||||
|
var current_notebook = getElement( "current_notebook_wrapper" );
|
||||||
|
var sibling_notebook = current_notebook;
|
||||||
|
|
||||||
|
// find the next sibling notebook node
|
||||||
|
do {
|
||||||
|
var sibling_notebook = sibling_notebook.nextSibling;
|
||||||
|
} while ( sibling_notebook && sibling_notebook.className != "link_area_item" );
|
||||||
|
|
||||||
|
removeElement( current_notebook );
|
||||||
|
if ( sibling_notebook )
|
||||||
|
// move the current notebook down after the previous notebook node
|
||||||
|
insertSiblingNodesAfter( sibling_notebook, current_notebook );
|
||||||
|
// if the current notebook is the last one, wrap it around to the top of the list
|
||||||
|
else {
|
||||||
|
var notebooks_area_title = getElement( "notebooks_area_title" );
|
||||||
|
insertSiblingNodesAfter( notebooks_area_title, current_notebook );
|
||||||
|
}
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
this.invoker.invoke( "/notebooks/move_down", "POST", {
|
||||||
|
"notebook_id": this.notebook_id
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
Wiki.prototype.display_message = function ( text, nodes, position_after ) {
|
Wiki.prototype.display_message = function ( text, nodes, position_after ) {
|
||||||
this.clear_messages();
|
this.clear_messages();
|
||||||
this.clear_pulldowns();
|
this.clear_pulldowns();
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from Tags import Div, Span, H4, A, Strong
|
from Tags import Div, Span, H4, A, Strong, Img
|
||||||
from Rounded_div import Rounded_div
|
from Rounded_div import Rounded_div
|
||||||
|
|
||||||
|
|
||||||
|
@ -115,7 +115,7 @@ class Link_area( Div ):
|
||||||
),
|
),
|
||||||
|
|
||||||
Div(
|
Div(
|
||||||
( len( linked_notebooks ) > 0 ) and H4( u"notebooks" ) or None,
|
( len( linked_notebooks ) > 0 ) and H4( u"notebooks", id = u"notebooks_area_title" ) or None,
|
||||||
[ ( nb.object_id == notebook.object_id ) and Rounded_div(
|
[ ( nb.object_id == notebook.object_id ) and Rounded_div(
|
||||||
u"current_notebook",
|
u"current_notebook",
|
||||||
A(
|
A(
|
||||||
|
@ -123,6 +123,12 @@ class Link_area( Div ):
|
||||||
href = u"/notebooks/%s" % nb.object_id,
|
href = u"/notebooks/%s" % nb.object_id,
|
||||||
id = u"notebook_%s" % nb.object_id,
|
id = u"notebook_%s" % nb.object_id,
|
||||||
),
|
),
|
||||||
|
( len( linked_notebooks ) > 1 ) and Span(
|
||||||
|
Img( src = u"/static/images/up_arrow.png", width = u"20", height = u"17", id = u"current_notebook_up" ),
|
||||||
|
Img( src = u"/static/images/down_arrow.png", width = u"20", height = u"17", id = u"current_notebook_down" ),
|
||||||
|
Span( id = "current_notebook_up_hover_preload" ),
|
||||||
|
Span( id = "current_notebook_down_hover_preload" ),
|
||||||
|
) or None,
|
||||||
class_ = u"link_area_item",
|
class_ = u"link_area_item",
|
||||||
) or
|
) or
|
||||||
Div(
|
Div(
|
||||||
|
|
|
@ -22,5 +22,6 @@ class Rounded_div( Div ):
|
||||||
Div.__init__(
|
Div.__init__(
|
||||||
self,
|
self,
|
||||||
div,
|
div,
|
||||||
|
id = u"%s_wrapper" % image_name,
|
||||||
class_ = u"%s_color" % image_name,
|
class_ = u"%s_color" % image_name,
|
||||||
)
|
)
|
||||||
|
|
Reference in New Issue