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:
parent
bcedc11e9a
commit
df3d170362
3
NEWS
3
NEWS
|
@ -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.
|
||||||
|
|
||||||
|
|
|
@ -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 ):
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 = []
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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."
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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",
|
||||||
),
|
),
|
||||||
|
|
|
@ -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"/"
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
Reference in New Issue