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) |