Add functions to soc/logic/document.py for dealing with partial_paths combined
authorTodd Larsen <tlarsen@google.com>
Wed, 01 Oct 2008 00:48:46 +0000
changeset 225 2590d6b83568
parent 224 35bf48c27eb6
child 226 a92b11181a49
Add functions to soc/logic/document.py for dealing with partial_paths combined with link_names. Add getWorksForOffsetAndLimit() to query for Documents for the /site/docs/list view.
app/soc/logic/document.py
app/soc/views/site/home.py
--- a/app/soc/logic/document.py	Wed Oct 01 00:45:30 2008 +0000
+++ b/app/soc/logic/document.py	Wed Oct 01 00:48:46 2008 +0000
@@ -22,22 +22,49 @@
   ]
 
 
+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
+
+import soc.logic.model
 
 import soc.models.document
-import soc.logic.model
+import soc.models.work
+
+ 
+WORK_PATH_LINKNAME_REGEX = re.compile(key_name.WORK_PATH_LINKNAME_PATTERN)
+
+def getPartsFromPath(path):
+  """Splits path string into partial_path and link_name.
+  
+  Returns:
+    {'partial_path': 'everything/but',
+     'link_name': 'link_name'}
+    or {} (empty dict) if string did not match WORK_PATH_LINKNAME_PATTERN.
+  """
+  path_linkname_match = WORK_PATH_LINKNAME_REGEX.match(path)
+  
+  if not path_linkname_match:
+    return {}
+
+  return path_linkname_match.groupdict()
 
 
-def getDocument(path, link_name):
+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)
+  name = key_name.nameDocument(path, link_name=link_name)
   
   if name:
     document = soc.models.document.Document.get_by_key_name(name)
@@ -47,7 +74,36 @@
   return document
 
 
-def updateOrCreateDocument(path, **document_properties):
+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:
@@ -61,11 +117,13 @@
     supplied path and properties.
   """
   # attempt to retrieve the existing Document
-  document = getDocument(path, document_properties['link_name'])
+  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(path, document_properties['link_name'])
+    name = key_name.nameDocument(document_properties['partial_path'],
+                                 document_properties['link_name'])
     document = soc.models.document.Document.get_or_insert(
         name, **document_properties)
 
@@ -75,4 +133,18 @@
   return soc.logic.model.updateModelProperties(document, **document_properties)
 
 
+def getWorksForOffsetAndLimit(offset=0, limit=0, cls=soc.models.work.Work):
+  """Returns Works for given offset and limit or None if not found.
+    
+  Args:
+    offset: offset in entities list which defines first entity to return
+    limit: max amount of entities to return
+    cls: Model class of items to return (including sub-classes of that type);
+      default is Work
+  """
+  query = db.GqlQuery(
+      'SELECT * FROM Work WHERE inheritance_line = :1 ORDER BY title',
+      key_name.getFullClassName(cls))
 
+  # Fetch one more to see if there should be a 'next' link
+  return query.fetch(limit+1, offset)  
--- a/app/soc/views/site/home.py	Wed Oct 01 00:45:30 2008 +0000
+++ b/app/soc/views/site/home.py	Wed Oct 01 00:48:46 2008 +0000
@@ -37,10 +37,10 @@
 from soc.logic import feed
 from soc.logic.site import id_user
 from soc.views import simple
+from soc.views.helpers import custom_widgets
 from soc.views.helpers import forms_helpers
 from soc.views.helpers import response_helpers
 from soc.views.helpers import template_helpers
-from soc.views.helpers import custom_widgets
 
 import soc.models.site_settings
 import soc.models.document
@@ -59,7 +59,8 @@
     model = soc.models.document.Document
     
     #: list of model fields which will *not* be gathered by the form
-    exclude = ['user','modified','created','link_name', 'inheritance_line']
+    exclude = ['partial_path', 'link_name',
+               'user', 'modified', 'created', 'inheritance_line']
 
 
 class SiteSettingsForm(forms_helpers.DbModelForm):
@@ -169,9 +170,9 @@
       content = document_form.cleaned_data.get('content')
       
       site_doc = soc.logic.document.updateOrCreateDocument(
-          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))
+          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))
       
       feed_url = settings_form.cleaned_data.get('feed_url')