app/soc/logic/document.py
changeset 225 2590d6b83568
parent 206 832335761384
child 248 95e0b84e71c5
equal deleted inserted replaced
224:35bf48c27eb6 225:2590d6b83568
    20 __authors__ = [
    20 __authors__ = [
    21   '"Pawel Solyga" <pawel.solyga@gmail.com>',
    21   '"Pawel Solyga" <pawel.solyga@gmail.com>',
    22   ]
    22   ]
    23 
    23 
    24 
    24 
       
    25 import re
       
    26 
    25 from google.appengine.ext import db
    27 from google.appengine.ext import db
    26 
    28 
    27 from soc.logic import key_name
    29 from soc.logic import key_name
       
    30 from soc.logic import out_of_band
       
    31 from soc.logic.site import id_user
       
    32 
       
    33 import soc.logic.model
    28 
    34 
    29 import soc.models.document
    35 import soc.models.document
    30 import soc.logic.model
    36 import soc.models.work
       
    37 
       
    38  
       
    39 WORK_PATH_LINKNAME_REGEX = re.compile(key_name.WORK_PATH_LINKNAME_PATTERN)
       
    40 
       
    41 def getPartsFromPath(path):
       
    42   """Splits path string into partial_path and link_name.
       
    43   
       
    44   Returns:
       
    45     {'partial_path': 'everything/but',
       
    46      'link_name': 'link_name'}
       
    47     or {} (empty dict) if string did not match WORK_PATH_LINKNAME_PATTERN.
       
    48   """
       
    49   path_linkname_match = WORK_PATH_LINKNAME_REGEX.match(path)
       
    50   
       
    51   if not path_linkname_match:
       
    52     return {}
       
    53 
       
    54   return path_linkname_match.groupdict()
    31 
    55 
    32 
    56 
    33 def getDocument(path, link_name):
    57 def getDocument(path, link_name=None):
    34   """Returns Document entity for a given path, or None if not found.  
    58   """Returns Document entity for a given path, or None if not found.  
    35     
    59     
    36   Args:
    60   Args:
    37     path: a request path of the Document that uniquely identifies it
    61     path: a request path of the Document that uniquely identifies it
       
    62     link_name: optional link name to append to path (when supplied,
       
    63       path is actually a "partial path" that needs to link name appended
       
    64       to it)
    38   """
    65   """
    39   # lookup by Doc:path key name
    66   # lookup by Doc:path key name
    40   name = key_name.nameDocument(path, link_name)
    67   name = key_name.nameDocument(path, link_name=link_name)
    41   
    68   
    42   if name:
    69   if name:
    43     document = soc.models.document.Document.get_by_key_name(name)
    70     document = soc.models.document.Document.get_by_key_name(name)
    44   else:
    71   else:
    45     document = None
    72     document = None
    46   
    73   
    47   return document
    74   return document
    48 
    75 
    49 
    76 
    50 def updateOrCreateDocument(path, **document_properties):
    77 def getDocumentIfPath(path, link_name=None):
       
    78   """Returns Document entity for supplied path if one exists.
       
    79   
       
    80   Args:
       
    81     path: path used in URLs to identify document
       
    82 
       
    83   Returns:
       
    84     * None if path is false.
       
    85     * Document entity that has supplied path
       
    86 
       
    87   Raises:
       
    88     out_of_band.ErrorResponse if path is not false, but no Document entity
       
    89     with the supplied path exists in the Datastore
       
    90   """
       
    91   if not path:
       
    92     # exit without error, to let view know that link_name was not supplied
       
    93     return None
       
    94 
       
    95   path_doc = getDocument(path, link_name=link_name)
       
    96     
       
    97   if path_doc:
       
    98     # a Document has this path, so return that corresponding Document entity
       
    99     return path_doc
       
   100 
       
   101   # else: a path was supplied, but there is no Document that has it
       
   102   raise out_of_band.ErrorResponse(
       
   103       'There is no document with a "path" of "%s".' % path, status=404)
       
   104 
       
   105 
       
   106 def updateOrCreateDocument(**document_properties):
    51   """Update existing Document entity, or create new one with supplied properties.
   107   """Update existing Document entity, or create new one with supplied properties.
    52 
   108 
    53   Args:
   109   Args:
    54     path: a request path of the Document that uniquely identifies it
   110     path: a request path of the Document that uniquely identifies it
    55     **document_properties: keyword arguments that correspond to Document entity
   111     **document_properties: keyword arguments that correspond to Document entity
    59     the Document entity corresponding to the path, with any supplied
   115     the Document entity corresponding to the path, with any supplied
    60     properties changed, or a new Document entity now associated with the 
   116     properties changed, or a new Document entity now associated with the 
    61     supplied path and properties.
   117     supplied path and properties.
    62   """
   118   """
    63   # attempt to retrieve the existing Document
   119   # attempt to retrieve the existing Document
    64   document = getDocument(path, document_properties['link_name'])
   120   document = getDocument(document_properties['partial_path'],
       
   121                          link_name=document_properties['link_name'])
    65 
   122 
    66   if not document:
   123   if not document:
    67     # document did not exist, so create one in a transaction
   124     # document did not exist, so create one in a transaction
    68     name = key_name.nameDocument(path, document_properties['link_name'])
   125     name = key_name.nameDocument(document_properties['partial_path'],
       
   126                                  document_properties['link_name'])
    69     document = soc.models.document.Document.get_or_insert(
   127     document = soc.models.document.Document.get_or_insert(
    70         name, **document_properties)
   128         name, **document_properties)
    71 
   129 
    72   # there is no way to be sure if get_or_insert() returned a new Document or
   130   # there is no way to be sure if get_or_insert() returned a new Document or
    73   # got an existing one due to a race, so update with document_properties anyway,
   131   # got an existing one due to a race, so update with document_properties anyway,
    74   # in a transaction
   132   # in a transaction
    75   return soc.logic.model.updateModelProperties(document, **document_properties)
   133   return soc.logic.model.updateModelProperties(document, **document_properties)
    76 
   134 
    77 
   135 
       
   136 def getWorksForOffsetAndLimit(offset=0, limit=0, cls=soc.models.work.Work):
       
   137   """Returns Works for given offset and limit or None if not found.
       
   138     
       
   139   Args:
       
   140     offset: offset in entities list which defines first entity to return
       
   141     limit: max amount of entities to return
       
   142     cls: Model class of items to return (including sub-classes of that type);
       
   143       default is Work
       
   144   """
       
   145   query = db.GqlQuery(
       
   146       'SELECT * FROM Work WHERE inheritance_line = :1 ORDER BY title',
       
   147       key_name.getFullClassName(cls))
    78 
   148 
       
   149   # Fetch one more to see if there should be a 'next' link
       
   150   return query.fetch(limit+1, offset)