Refactor nearly all the soc.logic code to use the Base class
Instead of having a lot of duplicate code, this patch aims
to reduce this duplication by introducing a Base abstraction.
Patch by: Sverre Rabbelier
Reviewed by: to-be-reviewed
--- a/app/soc/logic/__init__.py Sun Oct 12 00:08:54 2008 +0000
+++ b/app/soc/logic/__init__.py Sun Oct 12 00:12:53 2008 +0000
@@ -0,0 +1,119 @@
+#!/usr/bin/python2.5
+#
+# Copyright 2008 the Melange authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Various (Model) query functions.
+"""
+
+__authors__ = [
+ '"Sverre Rabbelier" <sverer@rabbelier.nl>',
+ ]
+
+
+import key_name
+import model
+import soc.models.document
+import soc.models.sponsor
+import soc.models.work
+import soc.models.site_settings
+
+
+class DocumentLogic(model.BaseLogic):
+ """Logic methods for the Document model
+ """
+
+ def __init__(self):
+ """Defines the name, key_name and model for this entity.
+ """
+
+ self._name = "document"
+ self._model = soc.models.document.Document
+ self._keyName = key_name.nameDocument
+ self._skip_properties = []
+
+
+class SettingsLogic(model.BaseLogic):
+ """Logic methods for the Settings model
+ """
+
+
+ def __init__(self):
+ """Defines the name, key_name and model for this entity.
+ """
+
+ self._name = "settings"
+ self._model = soc.models.site_settings.SiteSettings
+ self._keyName = key_name.nameSiteSettings
+ self._skip_properties = []
+
+
+class SponsorLogic(model.BaseLogic):
+ """Logic methods for the Sponsor model
+ """
+
+ def __init__(self):
+ """Defines the name, key_name and model for this entity.
+ """
+
+ self._name = "sponsor"
+ self._model = soc.models.sponsor.Sponsor
+ self._keyName = key_name.nameSponsor
+ self._skip_properties = []
+
+
+class UserLogic(model.BaseLogic):
+ """Logic methods for the User model
+ """
+
+ def __init__(self):
+ """Defines the name, key_name and model for this entity.
+ """
+
+ self._name = "user"
+ self._model = soc.models.user.User
+ self._keyName = key_name.nameUser
+ self._skip_properties = ['former_ids']
+
+ def _updateField(self, model, name, value):
+ """Special case logic for id.
+
+ When the id is changed, the former_ids field should be appended
+ with the old id.
+ """
+ if name == 'id' and model.id != value:
+ model.former_ids.append(model.id)
+
+ return True
+
+class WorkLogic(model.BaseLogic):
+ """Logic methods for the Work model
+ """
+
+ def __init__(self):
+ """Defines the name, key_name and model for this entity.
+ """
+
+ self._name = "work"
+ self._model = soc.models.work.Work
+ self._keyName = key_name.nameWork
+ self._skip_properties = []
+ # TODO(tlarsen) write a nameWork method
+
+
+document_logic = DocumentLogic()
+settings_logic = SettingsLogic()
+sponsor_logic = SponsorLogic()
+user_logic = UserLogic()
+work_logic = WorkLogic()
--- a/app/soc/logic/document.py Sun Oct 12 00:08:54 2008 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,115 +0,0 @@
-#!/usr/bin/python2.5
-#
-# Copyright 2008 the Melange authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Document (Model) query functions.
-"""
-
-__authors__ = [
- '"Pawel Solyga" <pawel.solyga@gmail.com>',
- '"Todd Larsen" <tlarsen@google.com>',
- ]
-
-
-import re
-
-from google.appengine.ext import db
-
-from soc.logic import key_name
-from soc.logic import out_of_band
-from soc.logic.site import id_user
-
-from soc.logic import model
-
-import soc.models.document
-
-
-def getDocument(path, link_name=None):
- """Returns Document entity for a given path, or None if not found.
-
- Args:
- path: a request path of the Document that uniquely identifies it
- link_name: optional link name to append to path (when supplied,
- path is actually a "partial path" that needs to link name appended
- to it)
- """
- # lookup by Doc:path key name
- name = key_name.nameDocument(path, link_name=link_name)
-
- if name:
- document = soc.models.document.Document.get_by_key_name(name)
- else:
- document = None
-
- return document
-
-
-def getDocumentIfPath(path, link_name=None):
- """Returns Document entity for supplied path if one exists.
-
- Args:
- path: path used in URLs to identify document
-
- Returns:
- * None if path is false.
- * Document entity that has supplied path
-
- Raises:
- out_of_band.ErrorResponse if path is not false, but no Document entity
- with the supplied path exists in the Datastore
- """
- if not path:
- # exit without error, to let view know that link_name was not supplied
- return None
-
- path_doc = getDocument(path, link_name=link_name)
-
- if path_doc:
- # a Document has this path, so return that corresponding Document entity
- return path_doc
-
- # else: a path was supplied, but there is no Document that has it
- raise out_of_band.ErrorResponse(
- 'There is no document with a "path" of "%s".' % path, status=404)
-
-
-def updateOrCreateDocument(**document_properties):
- """Update existing Document entity, or create new one with supplied properties.
-
- Args:
- path: a request path of the Document that uniquely identifies it
- **document_properties: keyword arguments that correspond to Document entity
- properties and their values
-
- Returns:
- the Document entity corresponding to the path, with any supplied
- properties changed, or a new Document entity now associated with the
- supplied path and properties.
- """
- # attempt to retrieve the existing Document
- document = getDocument(document_properties['partial_path'],
- link_name=document_properties['link_name'])
-
- if not document:
- # document did not exist, so create one in a transaction
- name = key_name.nameDocument(document_properties['partial_path'],
- document_properties['link_name'])
- document = soc.models.document.Document.get_or_insert(
- name, **document_properties)
-
- # there is no way to be sure if get_or_insert() returned a new Document or
- # got an existing one due to a race, so update with document_properties anyway,
- # in a transaction
- return soc.logic.model.updateModelProperties(document, **document_properties)
--- a/app/soc/logic/helper/access.py Sun Oct 12 00:08:54 2008 +0000
+++ b/app/soc/logic/helper/access.py Sun Oct 12 00:12:53 2008 +0000
@@ -97,7 +97,7 @@
checkIsLoggedIn(request)
id = users.get_current_user()
- user = id_user.getUserFromId(id)
+ user = soc.logic.user_logic.getFromFields(email=id)
if user:
return
--- a/app/soc/logic/key_name.py Sun Oct 12 00:08:54 2008 +0000
+++ b/app/soc/logic/key_name.py Sun Oct 12 00:12:53 2008 +0000
@@ -144,3 +144,13 @@
raise Error('"link_name" must be non-False: "%s"' % link_name)
return 'Group/Club:%s' % link_name
+
+
+def nameWork(link_name):
+ """Placeholder for work namer"""
+
+ if not link_name:
+ raise Error('"link_name" must be non-False: "%s"' % link_name)
+
+ return 'Work:%s' % link_name
+
--- a/app/soc/logic/model.py Sun Oct 12 00:08:54 2008 +0000
+++ b/app/soc/logic/model.py Sun Oct 12 00:12:53 2008 +0000
@@ -18,13 +18,17 @@
"""
__authors__ = [
+ '"Todd Larsen" <tlarsen@google.com>',
+ '"Sverre Rabbelier" <sverer@rabbelier.nl>',
'"Pawel Solyga" <pawel.solyga@gmail.com>',
- '"Todd Larsen" <tlarsen@google.com>',
]
from google.appengine.ext import db
+from soc.logic import key_name
+from soc.logic import out_of_band
+
def getFullClassName(cls):
"""Returns fully-qualified module.class name string."""
@@ -176,34 +180,167 @@
return None
-def updateModelProperties(model, **model_properties):
- """Update existing model entity using supplied model properties.
+class BaseLogic():
+ """Base logic for entity classes.
+
+ The BaseLogic class functions specific to Entity classes by relying
+ on the the child-classes to implement _model, _name and _key_name
+ """
+
+ def _updateField(self, model, name, value):
+ """Hook called when a field is updated.
+
+ Base classes should override if any special actions need to be
+ taken when a field is updated. The field is not updated if the
+ method does not return a True value.
+ """
+
+ return True
- Args:
- model: a model entity
- **model_properties: keyword arguments that correspond to model entity
- properties and their values
+ def getFromKeyName(self, key_name):
+ """"Returns User entity for key_name or None if not found.
+-
+- Args:
+- key_name: key name of entity
+ """
+ return self._model.get_by_key_name(key_name)
+
+ def getFromFields(self, **kwargs):
+ """Returns the entity for a given link name, or None if not found.
+
+ Args:
+ link_name: a link name of the entity that uniquely identifies it
+ """
+ # lookup by Sponsor key name
+ key_name = self.getKeyNameForFields(**kwargs)
- Returns:
- the original model entity with any supplied properties changed
- """
- def update():
- return _unsafeUpdateModelProperties(model, **model_properties)
+ if key_name:
+ entity = self._model.get_by_key_name(key_name)
+ else:
+ entity = None
+
+ return entity
+
+ def getIfFields(self, **kwargs):
+ """Returns Sponsor entity for supplied link name if one exists.
+
+ Args:
+ link_name: a link name of the Sponsor that uniquely identifies it
+
+ Returns:
+ * None if link name is false.
+ * Sponsor entity for supplied link_name
- return db.run_in_transaction(update)
+ Raises:
+ out_of_band.ErrorResponse if link name is not false, but no Sponsor entity
+ with the supplied link name exists in the Datastore
+ """
+ if not all(kwargs.values()):
+ # exit without error, to let view know that link_name was not supplied
+ return None
+
+ entity = self.getFromFields(**kwargs)
+
+ if entity:
+ # a Sponsor exist for this link_name, so return that Sponsor entity
+ return entity
+
+ fields = []
+
+ for key, value in kwargs.iteritems():
+ fields.extend('"%s" is "%s"' % (key, value))
+
+ # else: fields were supplied, but there is no Entity that has it
+ raise out_of_band.ErrorResponse(
+ 'There is no %s with %s.' % (self._name, ''.join(fields)), status=404)
+
+ def getKeyNameForFields(self, **kwargs):
+ """Return a Datastore key_name for a Sponsor from the link name.
+ Args:
+ link_name: a link name of the entity that uniquely identifies it
+ """
+ if not all(kwargs.values()):
+ return None
-def _unsafeUpdateModelProperties(model, **model_properties):
- """(see updateModelProperties)
+ return self._keyName(**kwargs)
+
+ def getForLimitAndOffset(self, limit, offset=0):
+ """Returns 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)
+ """
+ query = self._model.all()
+ return query.fetch(limit, offset)
- Like updateModelProperties(), but not run within a transaction.
- """
- properties = model.properties()
+ def updateModelProperties(self, model, **model_properties):
+ """Update existing model entity using supplied model properties.
+
+ Args:
+ model: a model entity
+ **model_properties: keyword arguments that correspond to model entity
+ properties and their values
+
+ Returns:
+ the original model entity with any supplied properties changed
+ """
+ def update():
+ return self._unsafeUpdateModelProperties(model, **model_properties)
+
+ return db.run_in_transaction(update)
+
+ def _unsafeUpdateModelProperties(self, model, **model_properties):
+ """(see updateModelProperties)
+
+ Like updateModelProperties(), but not run within a transaction.
+ """
+ properties = model.properties()
- for prop in properties.values():
- if prop.name in model_properties:
- value = model_properties[prop.name]
- prop.__set__(model, value)
+ for prop in properties.values():
+ name = prop.name
+
+ if not name in self._skip_properties and name in model_properties:
+ value = model_properties[prop.name]
+
+ if self._updateField(model, name, value):
+ prop.__set__(model, value)
+
+ model.put()
+ return model
+
+ def updateOrCreateFromKeyName(self, properties, key_name):
+ """Update existing entity, or create new one with supplied properties.
+
+ Args:
+ link_name: a link_name of the entity that uniquely identifies it
+ **properties: keyword arguments that correspond to entity
+ properties and their values
- model.put()
- return model
\ No newline at end of file
+ Returns:
+ the entity corresponding to the key_name, with any supplied
+ properties changed, or a new entity now associated with the
+ supplied key_name and properties.
+ """
+
+ entity = self.getFromKeyName(key_name)
+
+ if not entity:
+ # entity did not exist, so create one in a transaction
+ entity = self._model.get_or_insert(key_name, **properties)
+
+ # there is no way to be sure if get_or_insert() returned a new entity or
+ # got an existing one due to a race, so update with sponsor_properties anyway,
+ # in a transaction
+ return self.updateModelProperties(entity, **properties)
+
+ def updateOrCreateFromFields(self, properties, **kwargs):
+ """Like updateOrCreateFromKeyName, but resolves **kwargs to a key_name first
+ """
+
+ # attempt to retrieve the existing entity
+ key_name = self.getKeyNameForFields(**kwargs)
+
+ return self.updateOrCreateFromKeyName(properties, key_name)
--- 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
--- a/app/soc/logic/site/map.py Sun Oct 12 00:08:54 2008 +0000
+++ b/app/soc/logic/site/map.py Sun Oct 12 00:12:53 2008 +0000
@@ -30,7 +30,9 @@
from django.conf.urls import defaults
from django.utils import datastructures
-from soc.logic import path_link_name
+import soc.logic
+import soc.logic.path_link_name
+
from soc.logic.site import page
@@ -82,7 +84,7 @@
user_edit = page.Page(
page.Url(
- r'^user/profile/%s$' % path_link_name.LINKNAME_ARG_PATTERN,
+ r'^user/profile/%s$' % soc.logic.path_link_name.LINKNAME_ARG_PATTERN,
'soc.views.user.profile.edit'),
'User: Modify Existing User Profile',
parent=user_signout)
@@ -123,7 +125,7 @@
site_user_edit = page.Page(
page.Url(
- r'^site/user/profile/%s$' % path_link_name.LINKNAME_ARG_PATTERN,
+ r'^site/user/profile/%s$' % soc.logic.path_link_name.LINKNAME_ARG_PATTERN,
'soc.views.site.user.profile.edit'),
'Site: Modify Existing User Profile',
short_name='Modify Site User',
@@ -140,7 +142,7 @@
# Document views
docs_show = page.Page(
page.Url(
- r'^docs/show/%s$' % path_link_name.PATH_LINKNAME_ARGS_PATTERN,
+ r'^docs/show/%s$' % soc.logic.path_link_name.PATH_LINKNAME_ARGS_PATTERN,
'soc.views.docs.show.public'),
'Show Document',
parent=home)
@@ -156,7 +158,7 @@
site_docs_edit = page.Page(
page.Url(
- r'^site/docs/edit/%s$' % path_link_name.PATH_LINKNAME_ARGS_PATTERN,
+ r'^site/docs/edit/%s$' % soc.logic.path_link_name.PATH_LINKNAME_ARGS_PATTERN,
'soc.views.site.docs.edit.edit'),
'Site: Modify Existing Document',
short_name='Modify Site Document',
@@ -173,7 +175,7 @@
# Sponsor Group public view
sponsor_profile = page.Page(
page.Url(
- r'^sponsor/profile/%s' % path_link_name.LINKNAME_ARG_PATTERN,
+ r'^sponsor/profile/%s' % soc.logic.path_link_name.LINKNAME_ARG_PATTERN,
'soc.views.sponsor.profile.public'),
'Public Profile',
parent=home)
@@ -189,7 +191,7 @@
site_sponsor_delete = page.Page(
page.Url(
- r'^site/sponsor/profile/%s/delete$' % path_link_name.LINKNAME_ARG_PATTERN,
+ r'^site/sponsor/profile/%s/delete$' % soc.logic.path_link_name.LINKNAME_ARG_PATTERN,
'soc.views.site.sponsor.profile.delete'),
'Site: Delete Existing Sponsor',
short_name='Delete Site Sponsor',
@@ -197,7 +199,7 @@
site_sponsor_edit = page.Page(
page.Url(
- r'^site/sponsor/profile/%s' % path_link_name.LINKNAME_ARG_PATTERN,
+ r'^site/sponsor/profile/%s' % soc.logic.path_link_name.LINKNAME_ARG_PATTERN,
'soc.views.site.sponsor.profile.edit'),
'Site: Modify Existing Sponsor',
short_name='Modify Site Sponsor',
--- a/app/soc/logic/site/settings.py Sun Oct 12 00:08:54 2008 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-#!/usr/bin/python2.5
-#
-# Copyright 2008 the Melange authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""SiteSettings (Model) query functions.
-"""
-
-__authors__ = [
- '"Pawel Solyga" <pawel.solyga@gmail.com>',
- ]
-
-from google.appengine.ext import db
-
-from soc.logic import key_name
-
-import soc.models.site_settings
-import soc.logic.model
-
-
-def getSiteSettings(path):
- """Returns SiteSettings entity for a given path, or None if not found.
-
- Args:
- path: a request path of the SiteSettings that uniquely identifies it
- """
- # lookup by Settings:path key name
- name = key_name.nameSiteSettings(path)
-
- if name:
- site_settings = soc.models.site_settings.SiteSettings.get_by_key_name(name)
- else:
- site_settings = None
-
- return site_settings
-
-
-def updateOrCreateSiteSettings(path, **site_settings_properties):
- """Update existing SiteSettings entity, or create new one with supplied properties.
-
- Args:
- path: a request path of the SiteSettings that uniquely identifies it
- **site_settings_properties: keyword arguments that correspond to Document entity
- properties and their values
-
- Returns:
- the SiteSettings entity corresponding to the path, with any supplied
- properties changed, or a new SiteSettings entity now associated with the
- supplied path and properties.
- """
- # attempt to retrieve the existing Site Settings
- site_settings = getSiteSettings(path)
-
- if not site_settings:
- # site settings did not exist, so create one in a transaction
- name = key_name.nameSiteSettings(path)
- site_settings = soc.models.site_settings.SiteSettings.get_or_insert(
- name, **site_settings_properties)
-
- # there is no way to be sure if get_or_insert() returned a new SiteSettings or
- # got an existing one due to a race, so update with site_settings_properties anyway,
- # in a transaction
- return soc.logic.model.updateModelProperties(site_settings, **site_settings_properties)
--- a/app/soc/logic/sponsor.py Sun Oct 12 00:08:54 2008 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,150 +0,0 @@
-#!/usr/bin/python2.5
-#
-# Copyright 2008 the Melange authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Sponsor (Model) query functions.
-"""
-
-__authors__ = [
- '"Pawel Solyga" <pawel.solyga@gmail.com>',
- ]
-
-
-from soc.logic import key_name
-from soc.logic import out_of_band
-
-import soc.models.sponsor
-import soc.logic.model
-
-
-def doesLinkNameExist(link_name=None):
- """Returns True if link name exists in the Datastore.
-
- Args:
- link_name: link name used in URLs to identify Sponsor
- """
- if getSponsorFromLinkName(link_name):
- return True
- else:
- return False
-
-
-def getSponsorFromLinkName(link_name):
- """Returns Sponsor entity for a given link name, or None if not found.
-
- Args:
- link_name: a link name of the Sponsor that uniquely identifies it
- """
- # lookup by Sponsor key name
- sponsor_key_name = getSponsorKeyNameForLinkName(link_name)
-
- if sponsor_key_name:
- sponsor = soc.models.sponsor.Sponsor.get_by_key_name(sponsor_key_name)
- else:
- sponsor = None
-
- return sponsor
-
-
-def getSponsorIfLinkName(link_name=None):
- """Returns Sponsor entity for supplied link name if one exists.
-
- Args:
- link_name: a link name of the Sponsor that uniquely identifies it
-
- Returns:
- * None if link name is false.
- * Sponsor entity for supplied linkname
-
- Raises:
- out_of_band.ErrorResponse if link name is not false, but no Sponsor entity
- with the supplied link name exists in the Datastore
- """
- if not link_name:
- # exit without error, to let view know that link_name was not supplied
- return None
-
- linkname_sponsor = getSponsorFromLinkName(link_name=link_name)
-
- if linkname_sponsor:
- # a Sponsor exist for this linkname, so return that Sponsor entity
- return linkname_sponsor
-
- # else: a linkname was supplied, but there is no Sponsor that has it
- raise out_of_band.ErrorResponse(
- 'There is no sponsor with a "link name" of "%s".' % link_name, status=404)
-
-
-def getSponsorKeyNameForLinkName(link_name):
- """Return a Datastore key_name for a Sponsor from the link name.
-
- Args:
- link_name: a link name of the Sponsor that uniquely identifies it
- """
- if not link_name:
- return None
-
- return key_name.nameSponsor(link_name)
-
-
-def getSponsorsForLimitAndOffset(limit, offset=0):
- """Returns Sponsors 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)
- """
- query = soc.models.sponsor.Sponsor.all()
- return query.fetch(limit, offset)
-
-
-def updateOrCreateSponsorFromLinkName(sponsor_link_name, **sponsor_properties):
- """Update existing Sponsor entity, or create new one with supplied properties.
-
- Args:
- sponsor_name: a linkname of the Sponsor that uniquely identifies it
- **sponsor_properties: keyword arguments that correspond to Sponsor entity
- properties and their values
-
- Returns:
- the Sponsor entity corresponding to the path, with any supplied
- properties changed, or a new Sponsor entity now associated with the
- supplied path and properties.
- """
- # attempt to retrieve the existing Sponsor
- sponsor = getSponsorFromLinkName(sponsor_link_name)
-
- if not sponsor:
- # sponsor did not exist, so create one in a transaction
- sponsor_key_name = getSponsorKeyNameForLinkName(sponsor_link_name)
- sponsor = soc.models.sponsor.Sponsor.get_or_insert(
- sponsor_key_name, **sponsor_properties)
-
- # there is no way to be sure if get_or_insert() returned a new Sponsor or
- # got an existing one due to a race, so update with sponsor_properties anyway,
- # in a transaction
- return soc.logic.model.updateModelProperties(sponsor, **sponsor_properties)
-
-
-def deleteSponsor(sponsor):
- """Delete Sponsor entity.
-
- Args:
- sponsor: existing Sponsor entity
- """
- # TODO(pawel.solyga): check if Sponsor can be deleted
- # If Sponsor has Hosts or Programs it cannot be deleted
- sponsor.delete()
\ No newline at end of file
--- a/app/soc/logic/works.py Sun Oct 12 00:08:54 2008 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-#!/usr/bin/python2.5
-#
-# Copyright 2008 the Melange authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Works (Model) query functions.
-"""
-
-__authors__ = [
- '"Todd Larsen" <tlarsen@google.com>',
- ]
-
-
-from google.appengine.ext import db
-
-from soc.logic import model
-
-import soc.models.work
-
-
-def getWorksForLimitAndOffset(limit, offset=0, cls=soc.models.work.Work):
- """Returns Works 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)
- cls: Model class of items to return (including sub-classes of that type);
- default is Work
- """
- query = db.GqlQuery(model.buildOrderedQueryString(
- soc.models.work.Work, derived_class=cls, order_by='title'))
-
- return query.fetch(limit, offset)
--- a/app/soc/views/helper/responses.py Sun Oct 12 00:08:54 2008 +0000
+++ b/app/soc/views/helper/responses.py Sun Oct 12 00:12:53 2008 +0000
@@ -38,6 +38,7 @@
# In the development server
from google.appengine.runtime.apiproxy_errors import DeadlineExceededError
+import soc.logic
from soc.logic import system
from soc.logic.site import id_user
from soc.logic.site import sidebar
@@ -64,7 +65,9 @@
Any exceptions that django.template.loader.render_to_string() or
django.http.HttpResponse() might raise.
"""
- context = getUniversalContext(request, context=context)
+
+ if not context:
+ context = getUniversalContext(request)
if response_args is None:
response_args = {}
@@ -84,19 +87,14 @@
return http.HttpResponse('AssertionError')
-def getUniversalContext(request, context=None):
+def getUniversalContext(request):
"""Constructs a template context dict will many common variables defined.
Args:
request: the Django HTTP request object
- context: the template context dict to be updated in-place (pass in a copy
- if the original must not be modified), or None if a new one is to be
- created; any existing fields already present in the context dict passed
- in by the caller are left unaltered
-
+
Returns:
- updated template context dict supplied by the caller, or a new context
- dict if the caller supplied None
+ a new context dict containing:
{
'request': the Django HTTP request object passed in by the caller
@@ -110,26 +108,21 @@
'sidebar_menu_html': an HTML string that renders the sidebar menu
}
"""
- if context is None:
- context = {}
+
+ id = users.get_current_user()
+
+ context = {}
+ context['request'] = request
- # set some universal values if caller did not already set them
- context['request'] = context.get('request', request)
- context['id'] = id_user.getIdIfMissing(context.get('id', None))
- context['user'] = id_user.getUserIfMissing(context.get('user', None),
- context['id'])
- context['is_admin'] = context.get(
- 'is_admin', id_user.isIdDeveloper(id=context['id']))
- context['is_debug'] = context.get('is_debug', system.isDebug())
- context['sign_in'] = context.get(
- 'sign_in', users.create_login_url(request.path))
- context['sign_out'] = context.get(
- 'sign_out', users.create_logout_url(request.path))
+ if id:
+ context['id'] = id
+ context['user'] = soc.logic.user_logic.getFromFields(email=id.email())
+ context['is_admin'] = id_user.isIdDeveloper(id=id)
- if not context.get('sidebar_menu_html'):
- # pass the currently constructed context as keyword arguments to
- # all of the sidebar builder functions
- context['sidebar_menu_html'] = str(html_menu.UlMenu(
+ context['is_debug'] = system.isDebug()
+ context['sign_in'] = users.create_login_url(request.path)
+ context['sign_out'] = users.create_logout_url(request.path)
+ context['sidebar_menu_html'] = str(html_menu.UlMenu(
sidebar.buildSidebar(**context)))
return context
--- a/app/soc/views/person/profile.py Sun Oct 12 00:08:54 2008 +0000
+++ b/app/soc/views/person/profile.py Sun Oct 12 00:12:53 2008 +0000
@@ -52,7 +52,7 @@
exclude = ['user']
-def edit(request, program=None, linkname=None,
+def edit(request, program=None, link_name=None,
template='soc/person/profile/edit.html'):
"""View for a Person to modify the properties of a Person Model.
--- a/app/soc/views/simple.py Sun Oct 12 00:08:54 2008 +0000
+++ b/app/soc/views/simple.py Sun Oct 12 00:12:53 2008 +0000
@@ -22,6 +22,7 @@
'"Pawel Solyga" <pawel.solyga@gmail.com>',
]
+from google.appengine.api import users
from django.utils.translation import ugettext_lazy
@@ -32,54 +33,44 @@
import soc.views.helper.templates
-def templateWithLinkName(request,
- template='soc/base.html', linkname=None,
+def public(request, template='soc/base.html', link_name=None,
context=None):
- """A simple template view that expects a linkname extracted from the URL.
+ """A simple template view that expects a link_name extracted from the URL.
Args:
request: the standard Django HTTP request object
template: the template to use for rendering the view (or a search list
of templates)
- linkname: a site-unique "linkname" (usually extracted from the URL)
+ link_name: a site-unique "link_name" (usually extracted from the URL)
context: the context dict supplied to the template, which is modified
(so supply a copy if such modification is not acceptable)
- linkname: the linkname parameter is added to the context
- linkname_user: if the linkname exists for a User, that User
+ link_name: the link_name parameter is added to the context
+ link_name_user: if the link_name exists for a User, that User
is added to the context
Returns:
A subclass of django.http.HttpResponse containing the generated page.
"""
- context['linkname'] = linkname
- context = helper.responses.getUniversalContext(request, context=context)
+
+ template = helper.templates.makeSiblingTemplatesList(template, 'public.html')
+
+ if not context:
+ context = helper.responses.getUniversalContext(request)
try:
- context['linkname_user'] = id_user.getUserIfLinkName(linkname)
+ if link_name:
+ user = id_user.getUserFromLinkNameOrDie(link_name)
except out_of_band.ErrorResponse, error:
return errorResponse(request, error, template, context)
+ context['link_name'] = link_name
+ context['link_name_user'] = user
+
return helper.responses.respond(request, template, context)
-def public(request, template, linkname, context):
- """A convenience wrapper around templateWithLinkName() using 'public.html'.
-
- Args:
- request, linkname, context: see templateWithLinkName()
- template: the "sibling" template (or a search list of such templates)
- from which to construct the public.html template name (or names)
+DEF_ERROR_TMPL = 'soc/error.html'
- Returns:
- A subclass of django.http.HttpResponse containing the generated page.
- """
- return templateWithLinkName(
- request, linkname=linkname, context=context,
- template=helper.templates.makeSiblingTemplatesList(
- template, 'public.html'))
-
-
-DEF_ERROR_TMPL = 'soc/error.html'
def errorResponse(request, error, template, context):
"""Displays an error page for an out_of_band.ErrorResponse exception.
@@ -95,8 +86,10 @@
error_status: error.response_args['status'], or None if a status code
was not supplied to the ErrorResponse
"""
- context = helper.responses.getUniversalContext(request, context=context)
-
+
+ if not context:
+ context = helper.responses.getUniversalContext(request)
+
# make a list of possible "sibling" templates, then append a default
error_templates = helper.templates.makeSiblingTemplatesList(
template, 'error.html', default_template=DEF_ERROR_TMPL)
@@ -128,7 +121,9 @@
login_message: the caller can completely construct the message supplied
to the login template in lieu of using login_message_fmt
"""
- context = helper.responses.getUniversalContext(request, context=context)
+
+ if not context:
+ context = helper.responses.getUniversalContext(request)
# make a list of possible "sibling" templates, then append a default
login_templates = helper.templates.makeSiblingTemplatesList(
--- a/app/soc/views/site/docs/edit.py Sun Oct 12 00:08:54 2008 +0000
+++ b/app/soc/views/site/docs/edit.py Sun Oct 12 00:12:53 2008 +0000
@@ -28,7 +28,7 @@
from django import newforms as forms
from django.utils.translation import ugettext_lazy
-from soc.logic import document
+import soc.logic
from soc.logic import out_of_band
from soc.logic import path_link_name
from soc.logic.helper import access
@@ -76,7 +76,34 @@
ugettext_lazy('Document saved.'),
)
-def edit(request, partial_path=None, linkname=None,
+def getDocForForm(form):
+ """Extracts doc fields from a form and creates a new doc from it
+ """
+
+ user = users.get_current_user()
+ if user:
+ email = user.email()
+ else:
+ email = None
+
+ partial_path = form.cleaned_data.get('partial_path')
+ link_name = form.cleaned_data.get('link_name')
+
+ properties = {}
+ properties['partial_path'] = partial_path
+ properties['link_name'] = link_name
+ properties['title'] = form.cleaned_data.get('title')
+ properties['short_name'] = form.cleaned_data.get('short_name')
+ properties['abstract'] = form.cleaned_data.get('abstract')
+ properties['content'] = form.cleaned_data.get('content')
+ properties['user'] = soc.logic.user_logic.getFromFields(email=email)
+
+ doc = soc.logic.document_logic.updateOrCreateFromFields(properties,
+ partial_path=partial_path, link_name=link_name)
+
+ return doc
+
+def edit(request, partial_path=None, link_name=None,
template=DEF_SITE_DOCS_EDIT_TMPL):
"""View for a Developer to modify the properties of a Document Model entity.
@@ -109,7 +136,9 @@
# try to fetch Document entity corresponding to path if one exists
try:
- doc = document.getDocumentIfPath(path)
+ if path:
+ doc = soc.logic.document_logic.getFromFields(partial_path=partial_path,
+ link_name=link_name)
except out_of_band.ErrorResponse, error:
# show custom 404 page when path doesn't exist in Datastore
error.message = error.message + DEF_CREATE_NEW_DOC_MSG
@@ -119,22 +148,12 @@
form = EditForm(request.POST)
if form.is_valid():
- new_partial_path = form.cleaned_data.get('partial_path')
- new_linkname = form.cleaned_data.get('link_name')
- title = form.cleaned_data.get('title')
- short_name = form.cleaned_data.get('short_name')
- abstract = form.cleaned_data.get('abstract')
- content = form.cleaned_data.get('content')
-
- doc = soc.logic.document.updateOrCreateDocument(
- partial_path=new_partial_path, link_name=new_linkname,
- title=title, short_name=short_name, abstract=abstract,
- content=content, user=id_user.getUserFromId(logged_in_id))
+ doc = getDocForForm(form)
if not doc:
return http.HttpResponseRedirect('/')
- new_path = path_link_name.combinePath([new_partial_path, new_link_name])
+ new_path = path_link_name.combinePath([doc.partial_path, doc.link_name])
# redirect to new /site/docs/edit/new_path?s=0
# (causes 'Profile saved' message to be displayed)
@@ -237,17 +256,7 @@
form = CreateForm(request.POST)
if form.is_valid():
- new_partial_path = form.cleaned_data.get('partial_path')
- new_linkname = form.cleaned_data.get('link_name')
- title = form.cleaned_data.get('title')
- short_name = form.cleaned_data.get('short_name')
- abstract = form.cleaned_data.get('abstract')
- content = form.cleaned_data.get('content')
-
- doc = soc.logic.document.updateOrCreateDocument(
- partial_path=new_partial_path, link_name=new_linkname,
- title=title, short_name=short_name, abstract=abstract,
- content=content, user=id_user.getUserFromId(logged_in_id))
+ doc = getDocForForm(form)
if not doc:
return http.HttpResponseRedirect('/')
--- a/app/soc/views/site/docs/list.py Sun Oct 12 00:08:54 2008 +0000
+++ b/app/soc/views/site/docs/list.py Sun Oct 12 00:12:53 2008 +0000
@@ -22,7 +22,7 @@
]
-from soc.logic import works
+import soc.logic
from soc.logic.helper import access
from soc.views import simple
from soc.views import helper
@@ -59,8 +59,7 @@
offset=request.GET.get('offset'), limit=request.GET.get('limit'))
# Fetch one more to see if there should be a 'next' link
- docs = works.getWorksForLimitAndOffset(
- limit + 1, offset=offset, cls=soc.models.document.Document)
+ docs = soc.logic.work_logic.getForLimitAndOffset(limit + 1, offset=offset)
context['pagination_form'] = helper.lists.makePaginationForm(request, limit)
--- a/app/soc/views/site/home.py Sun Oct 12 00:08:54 2008 +0000
+++ b/app/soc/views/site/home.py Sun Oct 12 00:12:53 2008 +0000
@@ -33,6 +33,7 @@
from django import shortcuts
from django import newforms as forms
+import soc.logic
from soc.logic import out_of_band
from soc.logic import validate
from soc.logic.site import id_user
@@ -46,8 +47,6 @@
import soc.models.site_settings
import soc.models.document
-import soc.logic.document
-import soc.logic.site.settings
class DocumentForm(helper.forms.DbModelForm):
@@ -107,7 +106,7 @@
# create default template context for use with any templates
context = helper.responses.getUniversalContext(request)
- site_settings = soc.logic.site.settings.getSiteSettings(DEF_SITE_SETTINGS_PATH)
+ site_settings = soc.logic.settings_logic.getFromFields(path=DEF_SITE_SETTINGS_PATH)
if site_settings:
context['site_settings'] = site_settings
@@ -117,7 +116,7 @@
site_doc.content = helper.templates.unescape(site_doc.content)
context['site_document'] = site_doc
- return helper.responses.respond(request, template, context)
+ return helper.responses.respond(request, template, context=context)
DEF_SITE_HOME_EDIT_TMPL = 'soc/site/home/edit.html'
@@ -149,29 +148,37 @@
settings_form = SiteSettingsForm(request.POST)
if document_form.is_valid() and settings_form.is_valid():
- title = document_form.cleaned_data.get('title')
link_name = DEF_SITE_HOME_DOC_LINK_NAME
- short_name = document_form.cleaned_data.get('short_name')
- abstract = document_form.cleaned_data.get('abstract')
- content = document_form.cleaned_data.get('content')
-
+ partial_path=DEF_SITE_SETTINGS_PATH
logged_in_id = users.get_current_user()
+ user = soc.logic.user_logic.getFromFields(email=logged_in_id)
- site_doc = soc.logic.document.updateOrCreateDocument(
- partial_path=DEF_SITE_SETTINGS_PATH, link_name=link_name,
- title=title, short_name=short_name, abstract=abstract,
- content=content, user=id_user.getUserFromId(logged_in_id))
+ properties = {}
+ properties['title'] = document_form.cleaned_data.get('title')
+ properties['short_name'] = document_form.cleaned_data.get('short_name')
+ properties['abstract'] = document_form.cleaned_data.get('abstract')
+ properties['content'] = document_form.cleaned_data.get('content')
+ properties['link_name'] = link_name
+ properties['partial_path'] = partial_path
+ properties['id'] = logged_in_id
+ properties['user'] = user
+
+ #bla = dir(logged_in_id)
+ #raise self
+
+ site_doc = soc.logic.document_logic.updateOrCreateFromFields(
+ properties, partial_path=partial_path, link_name=link_name)
feed_url = settings_form.cleaned_data.get('feed_url')
- site_settings = soc.logic.site.settings.updateOrCreateSiteSettings(
- DEF_SITE_SETTINGS_PATH, home=site_doc, feed_url=feed_url)
+ site_settings = soc.logic.settings_logic.updateOrCreateFromFields(
+ {'feed_url' : feed_url, 'home' : site_doc}, path=DEF_SITE_SETTINGS_PATH)
context['notice'] = 'Site Settings saved.'
else: # request.method == 'GET'
# try to fetch SiteSettings entity by unique key_name
- site_settings = soc.logic.site.settings.getSiteSettings(
- DEF_SITE_SETTINGS_PATH)
+ site_settings = soc.logic.settings_logic.getFromFields(
+ path=DEF_SITE_SETTINGS_PATH)
if site_settings:
# populate form with the existing SiteSettings entity
--- a/app/soc/views/site/sponsor/list.py Sun Oct 12 00:08:54 2008 +0000
+++ b/app/soc/views/site/sponsor/list.py Sun Oct 12 00:12:53 2008 +0000
@@ -22,7 +22,6 @@
]
-from soc.logic import sponsor
from soc.logic.helper import access
from soc.views import simple
from soc.views import helper
@@ -48,7 +47,7 @@
offset=request.GET.get('offset'), limit=request.GET.get('limit'))
# Fetch one more to see if there should be a 'next' link
- sponsors = sponsor.getSponsorsForLimitAndOffset(limit + 1, offset=offset)
+ sponsors = soc.logic.sponsor_logic.getForLimitAndOffset(limit + 1, offset=offset)
context['pagination_form'] = helper.lists.makePaginationForm(request, limit)
--- a/app/soc/views/site/sponsor/profile.py Sun Oct 12 00:08:54 2008 +0000
+++ b/app/soc/views/site/sponsor/profile.py Sun Oct 12 00:12:53 2008 +0000
@@ -27,9 +27,9 @@
from django import http
from django import newforms as forms
+import soc.logic
from soc.logic import validate
from soc.logic import out_of_band
-from soc.logic import sponsor
from soc.logic.helper import access
from soc.logic.site import id_user
from soc.views import helper
@@ -60,7 +60,7 @@
link_name = self.cleaned_data.get('link_name')
if not validate.isLinkNameFormatValid(link_name):
raise forms.ValidationError("This link name is in wrong format.")
- if sponsor.doesLinkNameExist(link_name):
+ if soc.logic.sponsor_logic.getFromFields(link_name=link_name):
raise forms.ValidationError("This link name is already in use.")
return link_name
@@ -106,13 +106,13 @@
context = helper.responses.getUniversalContext(request)
logged_in_id = users.get_current_user()
- user = id_user.getUserFromId(logged_in_id)
+ user = soc.logic.user_logic.getFromFields(email=logged_in_id)
sponsor_form = None
existing_sponsor = None
# try to fetch Sponsor entity corresponding to link_name if one exists
try:
- existing_sponsor = soc.logic.sponsor.getSponsorIfLinkName(linkname)
+ existing_sponsor = soc.logic.sponsor_logic.getIfFields(link_name=link_name)
except out_of_band.ErrorResponse, error:
# show custom 404 page when link name doesn't exist in Datastore
error.message = error.message + DEF_CREATE_NEW_SPONSOR_MSG
@@ -144,8 +144,7 @@
fields['founder'] = user
form_ln = fields['link_name']
- form_sponsor = sponsor.updateOrCreateSponsorFromLinkName(form_ln,
- **fields)
+ form_sponsor = soc.logic.sponsor_logic.updateOrCreateFromFields(fields, link_name=form_ln)
if not form_sponsor:
return http.HttpResponseRedirect('/')
--- a/app/soc/views/site/user/list.py Sun Oct 12 00:08:54 2008 +0000
+++ b/app/soc/views/site/user/list.py Sun Oct 12 00:12:53 2008 +0000
@@ -22,6 +22,7 @@
]
+import soc.logic
from soc.logic.helper import access
from soc.logic.site import id_user
from soc.views import simple
@@ -59,7 +60,7 @@
offset=request.GET.get('offset'), limit=request.GET.get('limit'))
# Fetch one more to see if there should be a 'next' link
- users = id_user.getUsersForLimitAndOffset(limit + 1, offset=offset)
+ users = soc.logic.user_logic.getForLimitAndOffset(limit + 1, offset=offset)
context['pagination_form'] = helper.lists.makePaginationForm(request, limit)
--- a/app/soc/views/site/user/profile.py Sun Oct 12 00:08:54 2008 +0000
+++ b/app/soc/views/site/user/profile.py Sun Oct 12 00:12:53 2008 +0000
@@ -28,6 +28,7 @@
from django import newforms as forms
from django.utils.translation import ugettext_lazy
+import soc.logic
from soc.logic import validate
from soc.logic import out_of_band
from soc.logic.helper import access
@@ -126,7 +127,7 @@
if form_id:
# email provided, so attempt to look up user by email
- user = id_user.getUserFromId(form_id)
+ user = soc.logic.user_logic.getFromFields(id=form_id)
if user:
lookup_message = ugettext_lazy('User found by email.')
@@ -166,7 +167,7 @@
if user:
# User entity found, so populate form with existing User information
# context['found_user'] = user
- form = LookupForm(initial={'id': user.id.email,
+ form = LookupForm(initial={'id': user.id.email(),
'link_name': user.link_name})
if request.path.endswith('lookup'):
@@ -218,11 +219,12 @@
link_name = self.cleaned_data.get('link_name')
if not validate.isLinkNameFormatValid(link_name):
raise forms.ValidationError("This link name is in wrong format.")
- else:
- key_name = self.data.get('key_name')
- if not id_user.isLinkNameAvailableForId(
- link_name, id=id_user.getUserFromKeyName(key_name).id) :
- raise forms.ValidationError("This link name is already in use.")
+
+ user = soc.logic.user_logic.getFromKeyName(link_name)
+
+ if user and user.link_name != link_name:
+ raise forms.ValidationError("This link name is already in use.")
+
return link_name
def clean_id(self):
@@ -312,7 +314,7 @@
# populate form with the existing User entity
form = EditForm(initial={'key_name': user.key().name(),
- 'id': user.id.email, 'link_name': user.link_name,
+ 'id': user.id.email(), 'link_name': user.link_name,
'nick_name': user.nick_name, 'is_developer': user.is_developer})
else:
if request.GET.get(profile.SUBMIT_MSG_PARAM_NAME):
@@ -367,14 +369,14 @@
if not validate.isLinkNameFormatValid(link_name):
raise forms.ValidationError("This link name is in wrong format.")
else:
- if id_user.doesLinkNameExist(link_name):
+ if id_user.getUserFromLinkName(link_name):
raise forms.ValidationError("This link name is already in use.")
return link_name
def clean_id(self):
new_email = self.cleaned_data.get('id')
form_id = users.User(email=new_email)
- if id_user.isIdUser(form_id):
+ if soc.logic.user_logic.getFromFields(email=form_id):
raise forms.ValidationError("This account is already in use.")
return form_id
@@ -407,21 +409,23 @@
if form.is_valid():
form_id = form.cleaned_data.get('id')
- new_linkname = form.cleaned_data.get('link_name')
- nickname = form.cleaned_data.get('nick_name')
- is_developer = form.cleaned_data.get('is_developer')
+ link_name = form.cleaned_data.get('link_name')
- user = id_user.updateOrCreateUserFromId(id=form_id,
- link_name=new_linkname, nick_name=nickname,
- is_developer=is_developer)
+ properties = {}
+ properties['id'] = form_id
+ properties['link_name'] = link_name
+ properties['nick_name'] = form.cleaned_data.get('nick_name')
+ properties['is_developer'] = form.cleaned_data.get('is_developer')
+
+ user = soc.logic.user_logic.updateOrCreateFromFields(properties, email=form_id)
if not user:
return http.HttpResponseRedirect('/')
- # redirect to new /site/user/profile/new_linkname?s=0
+ # redirect to new /site/user/profile/new_link_name?s=0
# (causes 'Profile saved' message to be displayed)
return helper.responses.redirectToChangedSuffix(
- request, None, new_linkname,
+ request, None, link_name,
params=profile.SUBMIT_PROFILE_SAVED_PARAMS)
else: # method == 'GET':
# no link name specified, so start with an empty form
--- a/app/soc/views/user/profile.py Sun Oct 12 00:08:54 2008 +0000
+++ b/app/soc/views/user/profile.py Sun Oct 12 00:12:53 2008 +0000
@@ -28,6 +28,7 @@
from django import newforms as forms
from django.utils.translation import ugettext_lazy
+import soc.logic
from soc.logic import validate
from soc.logic import out_of_band
from soc.logic.site import id_user
@@ -56,8 +57,12 @@
link_name = self.cleaned_data.get('link_name')
if not validate.isLinkNameFormatValid(link_name):
raise forms.ValidationError("This link name is in wrong format.")
- elif not id_user.isLinkNameAvailableForId(link_name):
+
+ user = id_user.getUserFromLinkName(link_name)
+
+ if user and not id_user.doesLinkNameBelongToId(link_name, user.id):
raise forms.ValidationError("This link name is already in use.")
+
return link_name
@@ -109,7 +114,8 @@
# try to fetch User entity corresponding to link_name if one exists
try:
- linkname_user = id_user.getUserIfLinkName(linkname)
+ if link_name:
+ link_name_user = id_user.getUserFromLinkNameOrDie(link_name)
except out_of_band.ErrorResponse, error:
# show custom 404 page when link name doesn't exist in Datastore
return simple.errorResponse(request, error, template, context)
@@ -124,19 +130,21 @@
form = UserForm(request.POST)
if form.is_valid():
- new_linkname = form.cleaned_data.get('link_name')
- nickname = form.cleaned_data.get("nick_name")
+ new_link_name = form.cleaned_data.get('link_name')
+ properties = {}
+ properties['link_name'] = new_link_name
+ properties['nick_name'] = form.cleaned_data.get("nick_name")
+ properties['id'] = id
- user = id_user.updateOrCreateUserFromId(
- id, link_name=new_linkname, nick_name=nickname)
+ user = soc.logic.user_logic.updateOrCreateFromFields(properties, email=id)
# redirect to new /user/profile/new_link_name?s=0
# (causes 'Profile saved' message to be displayed)
return helper.responses.redirectToChangedSuffix(
request, link_name, new_link_name, params=SUBMIT_PROFILE_SAVED_PARAMS)
else: # request.method == 'GET'
- # try to fetch User entity corresponding to Google Account if one exists
- user = id_user.getUserFromId(id)
+ # try to fetch User entity corresponding to Google Account if one exists
+ user = soc.logic.user_logic.getFromFields(email=id)
if user:
# is 'Profile saved' parameter present, but referrer was not ourself?
--- a/app/soc/views/user/roles.py Sun Oct 12 00:08:54 2008 +0000
+++ b/app/soc/views/user/roles.py Sun Oct 12 00:12:53 2008 +0000
@@ -72,7 +72,7 @@
"""
#TODO(tlarsen): this module is currently a placeholder for future work
- # TODO: if linkname is empty or not a valid linkname on the site, display
+ # TODO: if link_name is empty or not a valid link_name on the site, display
# some sort of "user does not exist" page (a custom 404 page, maybe?).
return response_helpers.respond(request,