app/soc/logic/site/id_user.py
changeset 299 a1cc853a56e5
parent 263 9b39d93b677f
child 301 5d6d106afb23
--- a/app/soc/logic/site/id_user.py	Sun Oct 12 00:08:54 2008 +0000
+++ b/app/soc/logic/site/id_user.py	Sun Oct 12 00:12:53 2008 +0000
@@ -28,6 +28,7 @@
 from google.appengine.api import users
 from google.appengine.ext import db
 
+import soc.logic
 from soc.logic import key_name
 from soc.logic import model
 from soc.logic import out_of_band
@@ -35,107 +36,6 @@
 import soc.models.user
 
 
-def getUserKeyNameFromId(id):
-  """Return a Datastore key_name for a User derived from a Google Account.
-  
-  Args:
-    id: a Google Account (users.User) object
-  """
-  if not id:
-    return None
-
-  return key_name.nameUser(id.email())
-
-
-def getIdIfMissing(id=None):
-  """Gets Google Account of logged-in user (possibly None) if id is false.
-  
-  This is a convenience function that simplifies a lot of view code that
-  accepts an optional id argument from the caller (such as one looked up
-  already by another view that decides to "forward" the request to this
-  other view).
-
-  Args:
-    id: a Google Account (users.User) object, or None
-    
-  Returns:
-    If id is non-false, it is simply returned; otherwise, the Google Account
-    of currently logged-in user is returned (which could be None if no user
-    is logged in).
-  """
-  if not id:
-    # id not initialized, so check if a Google Account is currently logged in
-    id = users.get_current_user()
-
-  return id
-
-
-def getUsersForLimitAndOffset(limit, offset=0):
-  """Returns Users entities for given offset and limit or None if not found.
-    
-  Args:
-    limit: max amount of entities to return
-    offset: optional offset in entities list which defines first entity to
-      return; default is zero (first entity)
-  """
-  return model.getEntitiesForLimitAndOffset(
-      soc.models.user.User, limit, offset=offset, order_by='id')
-
-
-def getUserFromId(id):
-  """Returns User entity for a Google Account, or None if not found.  
-    
-  Args:
-    id: a Google Account (users.User) object
-  """
-  return soc.models.user.User.gql('WHERE id = :1', id).get()
-
-
-def getUserIfMissing(user, id):
-  """Conditionally returns User entity for a Google Account.
-  
-  This function is used to look up the User entity corresponding to the
-  supplied Google Account *if* the user parameter is false (usually None).
-  This function is basically a no-op if user already refers to a User
-  entity.  This is a convenience function that simplifies a lot of view
-  code that accepts an optional user argument from the caller (such as
-  one looked up already by another view that decides to "forward" the
-  HTTP request to this other view).
-
-  Args:
-    user: None (usually), or an existing User entity
-    id: a Google Account (users.User) object
-    
-  Returns:
-    * user (which may have already been None if passed in that way by the
-      caller) if id is false or user is non-false
-    * results of getUserFromId() if user is false and id is non-false
-  """
-  if id and (not user):
-    # Google Account supplied and User uninitialized, so look up User entity
-    user = getUserFromId(id)
-    
-  return user
-
-
-def getNearestUsers(id=None, link_name=None):
-  """Get User entities just before and just after the specified User.
-    
-  Args:
-    id: a Google Account (users.User) object; default is None (not supplied)
-    link_name: link name string; default is None (not supplied)
-
-  Returns:
-    User entities being those just before and just after the (possibly
-    non-existent) User for given id or link_name,
-      OR
-    possibly None if query had no results or neither id or link_name were
-    supplied.
-  """
-  return model.getNearestEntities(
-      soc.models.user.User, [('id', id), ('link_name', link_name)])
-
-
 def findNearestUsersOffset(width, id=None, link_name=None):
   """Finds offset of beginning of a range of Users around the nearest User.
   
@@ -156,40 +56,6 @@
     width, soc.models.user.User, [('id', id), ('link_name', link_name)])
 
 
-def doesUserExist(id):
-  """Returns True if User exists in the Datastore for a Google Account.
-    
-  Args:
-    id: a Google Account object
-  """
-  if getUserFromId(id):
-    return True
-  else:
-    return False
-
-
-def isIdUser(id=None):
-  """Returns True if a Google Account has it's User entity in datastore.
-
-  Args:
-    id: a Google Account (users.User) object; if id is not supplied,
-      the current logged-in user is checked
-  """
-  id = getIdIfMissing(id)
-
-  if not id:
-    # no Google Account was supplied or is logged in
-    return False
-
-  user = getUserFromId(id)
-
-  if not user:
-    # no User entity for this Google Account
-    return False
-  
-  return True
-
-
 def isIdDeveloper(id=None):
   """Returns True if a Google Account is a Developer with special privileges.
   
@@ -206,20 +72,25 @@
     id: a Google Account (users.User) object; if id is not supplied,
       the current logged-in user is checked
   """
-  id = getIdIfMissing(id)
- 
-  if not id:
+
+  # Get the currently logged in user
+  current_id = users.get_current_user()
+
+  if not (id or current_id):
     # no Google Account was supplied or is logged in, so an unspecified
     # User is definitely *not* a Developer
     return False
 
-  if id == users.get_current_user():
-    if users.is_current_user_admin():
-      # supplied id is current logged-in user, and that user is in the
-      # Administration->Developers list in the App Engine console
-      return True
-  
-  user = getUserFromId(id)
+  if (not id or id == current_id) and users.is_current_user_admin():
+    # no id supplied, or current logged-in user, and that user is in the
+    # Administration->Developers list in the App Engine console
+    return True
+
+  # If no id is specified, default to logged in user
+  if not id:
+    id = current_id
+
+  user = soc.logic.user_logic.getFromFields(id=id)
 
   if not user:
     # no User entity for this Google Account, and id is not the currently
@@ -241,7 +112,7 @@
       when existing_user is not supplied; default is None
   """
   if not existing_user:
-    existing_user = getUserFromKeyName(existing_key_name)
+    existing_user = soc.logic.user_logic.getFromKeyName(existing_key_name)
 
   if existing_user:
     old_email = existing_user.id.email()
@@ -253,7 +124,7 @@
     return True
   # else: "new" email truly is new to the existing User, so keep checking
 
-  if not isIdUser(new_id):
+  if not soc.logic.user_logic.getFromFields(id=new_id):
     # new email address also does not belong to any other User,
     # so it is available
     return True
@@ -271,201 +142,38 @@
   return soc.models.user.User.gql('WHERE link_name = :1', link_name).get()
 
 
-def getUserFromKeyName(key_name):
-  """Returns User entity for key_name or None if not found.
-    
-  Args:
-    key_name: key name of User entity
-  """
-  return soc.models.user.User.get_by_key_name(key_name)
-
-
-def getUserIfLinkName(link_name):
-  """Returns User entity for supplied link_name if one exists.
-  
-  Args:
-    link_name: link name used in URLs to identify user
-
-  Returns:
-    * None if link_name is false.
-    * User entity that has supplied link_name
+def getUserFromLinkNameOrDie(link_name):
+  """Like getUserFromLinkName but expects to find a user
 
   Raises:
-    out_of_band.ErrorResponse if link_name is not false, but no User entity
-    with the supplied link_name exists in the Datastore
+    out_of_band.ErrorResponse if no User entity is found
   """
-  if not link_name:
-    # exit without error, to let view know that link_name was not supplied
-    return None
 
-  link_name_user = getUserFromLinkName(link_name)
-    
-  if link_name_user:
-    # a User has this link name, so return that corresponding User entity
-    return link_name_user
+  user = getUserFromLinkName(link_name)
 
-  # else: a link name was supplied, but there is no User that has it
+  if user:
+    return user
+
   raise out_of_band.ErrorResponse(
       'There is no user with a "link name" of "%s".' % link_name, status=404)
 
 
-def isLinkNameAvailableForId(link_name, id=None):
-  """Indicates if link name is available for the given Google Account.
-  
-  Args:
-    link_name: link name used in URLs to identify user
-    id: a Google Account object; optional, current logged-in user will
-      be used (or False will be returned if no user is logged in)
-      
-  Returns:
-    True: the link name does not exist in the Datastore,
-      so it is currently "available" to any User
-    True: the link name exists and already belongs to the User entity
-      associated with the specified Google Account
-    False: the link name exists and belongs to a User entity other than
-      that associated with the supplied Google Account
-  """
-  link_name_exists = doesLinkNameExist(link_name)
- 
-  if not link_name_exists:
-    # if the link name does not exist, it is clearly available for any User
-    return True
-
-  return doesLinkNameBelongToId(link_name, id=id)
-
-
-def doesLinkNameExist(link_name=None):
-  """Returns True if link name exists in the Datastore.
-
-  Args:
-    link_name: link name used in URLs to identify user
-  """
-  if getUserFromLinkName(link_name):
-    return True
-  else:
-    return False
-
-
-def doesLinkNameBelongToId(link_name, id=None):
+def doesLinkNameBelongToId(link_name, id):
   """Returns True if supplied link name belongs to supplied Google Account.
   
   Args:
     link_name: link name used in URLs to identify user
-    id: a Google Account object; optional, current logged-in user will
-      be used (or False will be returned if no user is logged in)
+    id: a Google Account object
   """
-  id = getIdIfMissing(id)
-    
+
   if not id:
-    # id not supplied and no Google Account logged in, so link name cannot
-    # belong to an unspecified User
+    # link name cannot belong to an unspecified User
     return False
 
-  user = getUserFromId(id)
+  user = soc.logic.user_logic.getFromFields(email=id.email())
 
   if not user:
     # no User corresponding to id Google Account, so no link name at all 
     return False
 
-  if user.link_name != link_name:
-    # User exists for id, but does not have this link name
-    return False
-
-  return True  # link_name does actually belong to this Google Account
-
-
-def updateOrCreateUserFromId(id, **user_properties):
-  """Update existing User entity, or create new one with supplied properties.
-
-  Args:
-    id: a Google Account object
-    **user_properties: keyword arguments that correspond to User entity
-      properties and their values
-      
-  Returns:
-    the User entity corresponding to the Google Account, with any supplied
-    properties changed, or a new User entity now associated with the Google
-    Account and with the supplied properties
-  """
-  # attempt to retrieve the existing User
-  user = getUserFromId(id)
-  
-  if not user:
-    # user did not exist, so create one in a transaction
-    key_name = getUserKeyNameFromId(id)
-    user = soc.models.user.User.get_or_insert(
-      key_name, id=id, **user_properties)
-
-  # there is no way to be sure if get_or_insert() returned a new User or
-  # got an existing one due to a race, so update with user_properties anyway,
-  # in a transaction
-  return updateUserProperties(user, **user_properties)
-
-
-def updateUserForKeyName(key_name, **user_properties):
-  """Update existing User entity for keyname with supplied properties.
-
-  Args:
-    key_name: key name of User entity
-    **user_properties: keyword arguments that correspond to User entity
-      properties and their values
-
-  Returns:
-    the User entity corresponding to the Google Account, with any supplied
-    properties changed, or a new User entity now associated with the Google
-    Account and with the supplied properties
-  """
-  # attempt to retrieve the existing User
-  user = getUserFromKeyName(key_name)
-
-  if not user:
-    return None
-  
-  # there is no way to be sure if get_or_insert() returned a new User or
-  # got an existing one due to a race, so update with user_properties anyway,
-  # in a transaction
-  return updateUserProperties(user, **user_properties)
-
-
-def updateUserProperties(user, **user_properties):
-  """Update existing User entity using supplied User properties.
-
-  Args:
-    user: a User entity
-    **user_properties: keyword arguments that correspond to User entity
-      properties and their values
-      
-  Returns:
-    the original User entity with any supplied properties changed 
-  """
-  def update():
-    return _unsafeUpdateUserProperties(user, **user_properties)
-
-  return db.run_in_transaction(update)
-
-
-def _unsafeUpdateUserProperties(user, **user_properties):
-  """(see updateUserProperties)
-  
-  Like updateUserProperties(), but not run within a transaction. 
-  """
-  properties = user.properties()
-  
-  for prop in properties.values():
-    if prop.name in user_properties:
-      if prop.name == 'former_ids':
-        # former_ids cannot be overwritten directly
-        continue
-
-      value = user_properties[prop.name]
-
-      if prop.name == 'id':
-        old_id = user.id
-
-        if value != old_id:
-          user.former_ids.append(old_id)
-
-      prop.__set__(user, value)
-        
-  user.put()
-  return user
+  return user.link_name == link_name