witten
/
luminotes
Archived
1
0
Fork 0

View groups that you're a member of, with an indicatation if you're an admin of that group.

- modify controller.Users.current() to return the user's groups
    - update test_current() unit tests to expect empty groups list in results
  - modify Main_page, Notebook_rss, Front_page, Tour_page, and Upgrade_page to accept a new groups parameter
    - Main_page should add it as a hidden HTML variable
  - update Wiki.js to read the hidden groups variable and display the groups in account settings
This commit is contained in:
Dan Helfman 2008-05-28 16:05:38 -07:00
parent bcedc11e9a
commit df3d170362
12 changed files with 69 additions and 5 deletions

3
NEWS
View File

@ -1,3 +1,6 @@
1.4.0: ??
*
1.3.40: May 27, 2008 1.3.40: May 27, 2008
* Added some minor product page tweaks like meta description tags. * Added some minor product page tweaks like meta description tags.

View File

@ -5,6 +5,7 @@ import cherrypy
from pytz import utc from pytz import utc
from datetime import datetime, timedelta from datetime import datetime, timedelta
from model.User import User from model.User import User
from model.Group import Group
from model.Notebook import Notebook from model.Notebook import Notebook
from model.Note import Note from model.Note import Note
from model.Password_reset import Password_reset from model.Password_reset import Password_reset
@ -494,6 +495,7 @@ class Users( object ):
'login_url': url, 'login_url': url,
'logout_url': url, 'logout_url': url,
'rate_plan': rateplandict, 'rate_plan': rateplandict,
'groups': groups,
} }
@raise Validation_error: one of the arguments is invalid @raise Validation_error: one of the arguments is invalid
@raise Access_error: user_id or anonymous user unknown @raise Access_error: user_id or anonymous user unknown
@ -514,9 +516,11 @@ class Users( object ):
if user_id and user_id != anonymous.object_id: if user_id and user_id != anonymous.object_id:
notebooks = self.__database.select_many( Notebook, user.sql_load_notebooks() ) notebooks = self.__database.select_many( Notebook, user.sql_load_notebooks() )
groups = self.__database.select_many( Group, user.sql_load_groups() )
# if the user is not logged in, return a login URL # if the user is not logged in, return a login URL
else: else:
notebooks = [] notebooks = []
groups = []
if len( anon_notebooks ) > 0 and anon_notebooks[ 0 ]: if len( anon_notebooks ) > 0 and anon_notebooks[ 0 ]:
main_notebook = anon_notebooks[ 0 ] main_notebook = anon_notebooks[ 0 ]
login_note = self.__database.select_one( Note, main_notebook.sql_load_note_by_title( u"login" ) ) login_note = self.__database.select_one( Note, main_notebook.sql_load_note_by_title( u"login" ) )
@ -529,6 +533,7 @@ class Users( object ):
login_url = login_url, login_url = login_url,
logout_url = self.__https_url + u"/users/logout", logout_url = self.__https_url + u"/users/logout",
rate_plan = ( user.rate_plan < len( self.__rate_plans ) ) and self.__rate_plans[ user.rate_plan ] or {}, rate_plan = ( user.rate_plan < len( self.__rate_plans ) ) and self.__rate_plans[ user.rate_plan ] or {},
groups = groups,
) )
def calculate_storage( self, user ): def calculate_storage( self, user ):

View File

@ -7,6 +7,7 @@ class Stub_database( object ):
# map of object id to list of saved objects (presumably in increasing order of revisions) # map of object id to list of saved objects (presumably in increasing order of revisions)
self.objects = {} self.objects = {}
self.user_notebook = {} # map of user_id to ( notebook_id, read_write, owner ) self.user_notebook = {} # map of user_id to ( notebook_id, read_write, owner )
self.user_group = {} # map of user_id to ( group_id, admin )
self.last_saved_obj = None self.last_saved_obj = None
self.last_saved_user = None self.last_saved_user = None
self.__next_id = 0 self.__next_id = 0

View File

@ -179,6 +179,25 @@ class Test_controller( object ):
User.sql_highest_notebook_rank = lambda self: \ User.sql_highest_notebook_rank = lambda self: \
lambda database: sql_highest_notebook_rank( self, database ) lambda database: sql_highest_notebook_rank( self, database )
def sql_load_groups( self, database ):
groups = []
group_infos = database.user_group.get( self.object_id )
if not group_infos: return []
for group_info in group_infos:
( group_id, admin ) = group_info
group = database.objects.get( group_id )[ -1 ]
group.admin = admin
groups.append( group )
groups.sort( lambda a, b: cmp( a.name, b.name ) )
return groups
User.sql_load_groups = lambda self: \
lambda database: sql_load_groups( 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 = []

View File

@ -195,6 +195,8 @@ 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
assert result[ u"groups" ] == []
def test_current_after_signup_with_invite_id( self ): def test_current_after_signup_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()
@ -275,6 +277,8 @@ 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
assert result[ u"groups" ] == []
def test_current_after_signup_with_rate_plan( self ): def test_current_after_signup_with_rate_plan( self ):
result = self.http_post( "/users/signup", dict( result = self.http_post( "/users/signup", dict(
username = self.new_username, username = self.new_username,
@ -331,6 +335,8 @@ 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
assert result[ u"groups" ] == []
def test_signup_with_different_passwords( self ): def test_signup_with_different_passwords( self ):
result = self.http_post( "/users/signup", dict( result = self.http_post( "/users/signup", dict(
username = self.new_username, username = self.new_username,
@ -461,6 +467,8 @@ 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
assert result[ u"groups" ] == []
def test_current_after_demo_twice( self ): def test_current_after_demo_twice( self ):
result = self.http_post( "/users/demo", dict() ) result = self.http_post( "/users/demo", dict() )
session_id = result[ u"session_id" ] session_id = result[ u"session_id" ]
@ -562,6 +570,8 @@ 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
assert result[ u"groups" ] == []
def test_current_anonymous( self ): def test_current_anonymous( self ):
result = cherrypy.root.users.current( self.anonymous.object_id ) result = cherrypy.root.users.current( self.anonymous.object_id )
@ -586,6 +596,8 @@ 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
assert result[ u"groups" ] == []
def test_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()

View File

@ -229,7 +229,7 @@ class User( Persistent ):
return \ return \
""" """
select select
luminiotes_group_current.*, user_group.admin luminotes_group_current.*, user_group.admin
from from
user_group, luminotes_group_current user_group, luminotes_group_current
where where

View File

@ -19,6 +19,7 @@ function Wiki( invoker ) {
this.after_login = getElement( "after_login" ).value; this.after_login = getElement( "after_login" ).value;
this.signup_plan = getElement( "signup_plan" ).value; this.signup_plan = getElement( "signup_plan" ).value;
this.email_address = getElement( "email_address" ).value || ""; this.email_address = getElement( "email_address" ).value || "";
this.groups = evalJSON( getElement( "groups" ).value );
this.font_size = null; this.font_size = null;
this.small_toolbar = false; this.small_toolbar = false;
this.large_toolbar_bottom = 0; this.large_toolbar_bottom = 0;
@ -1704,8 +1705,28 @@ Wiki.prototype.display_settings = function () {
return; return;
} }
var group_list = createDOM( "ul" );
for ( var i in this.groups ) {
var group = this.groups[ i ];
var item = createDOM( "li", {} );
appendChildNodes( item, group.name + " " );
if ( group.admin )
appendChildNodes( item, "(admin)" );
appendChildNodes( group_list, item );
}
if ( this.groups.length == 0 ) {
var item = createDOM( "li", {}, "You're not a member of any groups." );
appendChildNodes( group_list, item );
}
var div = createDOM( "div", {}, var div = createDOM( "div", {},
createDOM( "form", { "id": "settings_form" }, createDOM( "form", { "id": "settings_form" },
createDOM( "p", {},
createDOM( "b", {}, "group membership" ),
createDOM( "br", {} ),
group_list
),
createDOM( "p", {}, createDOM( "p", {},
createDOM( "b", {}, "email address" ), createDOM( "b", {}, "email address" ),
createDOM( "br", {} ), createDOM( "br", {} ),
@ -1719,7 +1740,7 @@ Wiki.prototype.display_settings = function () {
{ "type": "submit", "name": "settings_button", "id": "settings_button", "class": "button", "value": "save settings" } { "type": "submit", "name": "settings_button", "id": "settings_button", "class": "button", "value": "save settings" }
) )
), ),
createDOM( "p", {}, createDOM( "p", { "class": "small_text" },
"Your email address will ", "Your email address will ",
createDOM( "a", { "href": "/privacy", "target": "_new" }, "never be shared" ), createDOM( "a", { "href": "/privacy", "target": "_new" }, "never be shared" ),
". It will only be used for password resets, contacting you about account problems, and the from address in any invite emails you send." ". It will only be used for password resets, contacting you about account problems, and the from address in any invite emails you send."

View File

@ -3,7 +3,7 @@ from Tags import Div, Img, A, P, Table, Tr, Td, Li, Span, I, Br, Ul, Li
class Front_page( Product_page ): class Front_page( Product_page ):
def __init__( self, user, notebooks, first_notebook, login_url, logout_url, rate_plan ): def __init__( self, user, notebooks, first_notebook, login_url, logout_url, rate_plan, groups ):
Product_page.__init__( Product_page.__init__(
self, self,
user, user,

View File

@ -36,6 +36,7 @@ class Main_page( Page ):
signup_plan = None, signup_plan = None,
signup_yearly = None, signup_yearly = None,
recent_notes = None, recent_notes = None,
groups = None,
): ):
startup_note_ids = [ startup_note.object_id for startup_note in startup_notes ] startup_note_ids = [ startup_note.object_id for startup_note in startup_notes ]
@ -144,6 +145,7 @@ class Main_page( Page ):
Input( type = u"hidden", name = u"after_login", id = u"after_login", value = after_login ), Input( type = u"hidden", name = u"after_login", id = u"after_login", value = after_login ),
Input( type = u"hidden", name = u"signup_plan", id = u"signup_plan", value = signup_plan ), Input( type = u"hidden", name = u"signup_plan", id = u"signup_plan", value = signup_plan ),
Input( type = u"hidden", name = u"email_address", id = u"email_address", value = user.email_address ), Input( type = u"hidden", name = u"email_address", id = u"email_address", value = user.email_address ),
Input( type = u"hidden", name = u"groups", id = u"groups", value = json( groups ) ),
Div( Div(
id = u"status_area", id = u"status_area",
), ),

View File

@ -29,6 +29,7 @@ class Notebook_rss( Rss_channel ):
signup_plan = None, signup_plan = None,
signup_yearly = None, signup_yearly = None,
recent_notes = None, recent_notes = None,
groups = None,
): ):
if notebook.name == u"Luminotes": if notebook.name == u"Luminotes":
notebook_path = u"/" notebook_path = u"/"

View File

@ -3,7 +3,7 @@ from Tags import Div, H1, Img, A, Ol, Li, P, Span, I, Br
class Tour_page( Product_page ): class Tour_page( Product_page ):
def __init__( self, user, notebooks, first_notebook, login_url, logout_url, rate_plan ): def __init__( self, user, notebooks, first_notebook, login_url, logout_url, rate_plan, groups ):
Product_page.__init__( Product_page.__init__(
self, self,
user, user,

View File

@ -3,7 +3,7 @@ from Tags import Div, H1, Img, A, P, Table, Th, Tr, Td, Li, Span, I, Br, Ul, Li,
class Upgrade_page( Product_page ): class Upgrade_page( Product_page ):
def __init__( self, user, notebooks, first_notebook, login_url, logout_url, rate_plan, rate_plans, unsubscribe_button ): def __init__( self, user, notebooks, first_notebook, login_url, logout_url, rate_plan, groups, rate_plans, unsubscribe_button ):
MEGABYTE = 1024 * 1024 MEGABYTE = 1024 * 1024
rate_plans = list( rate_plans ) rate_plans = list( rate_plans )
rate_plans.reverse() # show rate plans highest to lowest rate_plans.reverse() # show rate plans highest to lowest