allura
Revision | 34b11ad3357c4ee79b84ebf5b79329606430a4d0 (tree) |
---|---|
Zeit | 2012-04-19 00:29:19 |
Autor | bolkimen <bolkimen@yaho...> |
Commiter | bolkimen |
ticket:39 add my_projects macro
@@ -132,10 +132,9 @@ def project_blog_posts(max_number=5, sort='timestamp', summary=False, mount_poin | ||
132 | 132 | security.has_access(post.app.project, 'read', project=post.app.project)()) |
133 | 133 | return output |
134 | 134 | |
135 | -@macro('neighborhood-wiki') | |
136 | -def projects(category=None, display_mode='grid', sort='last_updated', | |
135 | +def get_projects_for_macro(category=None, display_mode='grid', sort='last_updated', | |
137 | 136 | show_total=False, limit=100, labels='', award='', private=False, |
138 | - columns=1, show_proj_icon=True, show_download_button=True): | |
137 | + columns=1, show_proj_icon=True, show_download_button=True, macro_type='projects'): | |
139 | 138 | from allura.lib.widgets.project_list import ProjectList |
140 | 139 | from allura.lib import utils |
141 | 140 | from allura import model as M |
@@ -172,37 +171,77 @@ def projects(category=None, display_mode='grid', sort='last_updated', | ||
172 | 171 | elif sort == '_id': |
173 | 172 | sort_key, sort_dir = '_id', pymongo.DESCENDING |
174 | 173 | |
175 | - projects = [] | |
176 | - if private: | |
177 | - # Only return private projects. | |
178 | - # Can't filter these with a mongo query directly - have to iterate | |
179 | - # through and check the ACL of each project. | |
180 | - for chunk in utils.chunked_find(M.Project, q, sort_key=sort_key, | |
181 | - sort_dir=sort_dir): | |
182 | - projects.extend([p for p in chunk if p.private]) | |
183 | - total = len(projects) | |
184 | - if sort == 'random': | |
185 | - projects = random.sample(projects, min(limit, total)) | |
174 | + if macro_type == 'projects': | |
175 | + projects = [] | |
176 | + if private: | |
177 | + # Only return private projects. | |
178 | + # Can't filter these with a mongo query directly - have to iterate | |
179 | + # through and check the ACL of each project. | |
180 | + for chunk in utils.chunked_find(M.Project, q, sort_key=sort_key, | |
181 | + sort_dir=sort_dir): | |
182 | + projects.extend([p for p in chunk if p.private]) | |
183 | + total = len(projects) | |
184 | + if sort == 'random': | |
185 | + projects = random.sample(projects, min(limit, total)) | |
186 | + else: | |
187 | + projects = projects[:limit] | |
186 | 188 | else: |
187 | - projects = projects[:limit] | |
188 | - else: | |
189 | - total = None | |
189 | + total = None | |
190 | + if sort == 'random': | |
191 | + # MongoDB doesn't have a random sort built in, so... | |
192 | + # 1. Do a direct pymongo query (faster than ORM) to fetch just the | |
193 | + # _ids of objects that match our criteria | |
194 | + # 2. Choose a random sample of those _ids | |
195 | + # 3. Do an ORM query to fetch the objects with those _ids | |
196 | + # 4. Shuffle the results | |
197 | + from ming.orm import mapper | |
198 | + m = mapper(M.Project) | |
199 | + collection = M.main_doc_session.db[m.collection.m.collection_name] | |
200 | + docs = list(collection.find(q, {'_id': 1})) | |
201 | + if docs: | |
202 | + ids = [doc['_id'] for doc in | |
203 | + random.sample(docs, min(limit, len(docs)))] | |
204 | + if '_id' in q: | |
205 | + ids = list(set(q['_id']['$in']).intersection(ids)) | |
206 | + q['_id'] = {'$in': ids} | |
207 | + projects = M.Project.query.find(q).all() | |
208 | + random.shuffle(projects) | |
209 | + else: | |
210 | + projects = M.Project.query.find(q).limit(limit).sort(sort_key, | |
211 | + sort_dir).all() | |
212 | + | |
213 | + elif macro_type == 'my_projects': | |
214 | + projects = [] | |
215 | + myproj_user = c.user.anonymous() | |
216 | + | |
217 | + if c.project.neighborhood.name == "Users" and c.project.name[:2] == u"u/": | |
218 | + username = c.project.name[2:] | |
219 | + myproj_user = M.User.query.get(username=username) | |
220 | + if 'neighborhood_id' in q: | |
221 | + del q['neighborhood_id'] | |
222 | + else: | |
223 | + admin_role_id = M.ProjectRole.query.get(project_id=c.project._id,name='Admin')._id | |
224 | + if c.user is None or c.user == c.user.anonymous(): | |
225 | + project_users_roles = M.ProjectRole.query.find(dict(name=None, project_id=c.project._id)).all() | |
226 | + for ur in project_users_roles: | |
227 | + if admin_role_id in ur.roles: | |
228 | + myproj_user = ur.user | |
229 | + break | |
230 | + else: | |
231 | + myproj_user = c.user | |
232 | + | |
233 | + # Get projects ids | |
234 | + ids = [] | |
235 | + for p in myproj_user.my_projects(): | |
236 | + ids.append(p._id) | |
237 | + if '_id' in q: | |
238 | + ids = list(set(q['_id']['$in']).intersection(ids)) | |
239 | + q['_id'] = {'$in': ids} | |
240 | + | |
190 | 241 | if sort == 'random': |
191 | - # MongoDB doesn't have a random sort built in, so... | |
192 | - # 1. Do a direct pymongo query (faster than ORM) to fetch just the | |
193 | - # _ids of objects that match our criteria | |
194 | - # 2. Choose a random sample of those _ids | |
195 | - # 3. Do an ORM query to fetch the objects with those _ids | |
196 | - # 4. Shuffle the results | |
197 | - from ming.orm import mapper | |
198 | - m = mapper(M.Project) | |
199 | - collection = M.main_doc_session.db[m.collection.m.collection_name] | |
200 | - docs = list(collection.find(q, {'_id': 1})) | |
201 | - if docs: | |
202 | - ids = [doc['_id'] for doc in | |
203 | - random.sample(docs, min(limit, len(docs)))] | |
204 | - projects = M.Project.query.find(dict(_id={'$in': ids})).all() | |
205 | - random.shuffle(projects) | |
242 | + ids = random.sample(ids, min(limit, len(ids))) | |
243 | + projects = M.Project.query.find(q).all() | |
244 | + random.shuffle(projects) | |
206 | 245 | else: |
207 | 246 | projects = M.Project.query.find(q).limit(limit).sort(sort_key, |
208 | 247 | sort_dir).all() |
@@ -222,6 +261,25 @@ def projects(category=None, display_mode='grid', sort='last_updated', | ||
222 | 261 | (total, response) |
223 | 262 | return response |
224 | 263 | |
264 | + | |
265 | +@macro('neighborhood-wiki') | |
266 | +def projects(category=None, display_mode='grid', sort='last_updated', | |
267 | + show_total=False, limit=100, labels='', award='', private=False, | |
268 | + columns=1, show_proj_icon=True, show_download_button=True): | |
269 | + return get_projects_for_macro(category=category, display_mode=display_mode, sort=sort, | |
270 | + show_total=show_total, limit=limit, labels=labels, award=award, private=private, | |
271 | + columns=columns, show_proj_icon=show_proj_icon, show_download_button=show_download_button, | |
272 | + macro_type='projects') | |
273 | + | |
274 | +@macro() | |
275 | +def my_projects(category=None, display_mode='grid', sort='last_updated', | |
276 | + show_total=False, limit=100, labels='', award='', private=False, | |
277 | + columns=1, show_proj_icon=True, show_download_button=True): | |
278 | + return get_projects_for_macro(category=category, display_mode=display_mode, sort=sort, | |
279 | + show_total=show_total, limit=limit, labels=labels, award=award, private=private, | |
280 | + columns=columns, show_proj_icon=show_proj_icon, show_download_button=show_download_button, | |
281 | + macro_type='my_projects') | |
282 | + | |
225 | 283 | @macro() |
226 | 284 | def project_screenshots(): |
227 | 285 | from allura.lib.widgets.project_list import ProjectScreenshots |
@@ -309,7 +309,7 @@ class Project(MappedClass): | ||
309 | 309 | roles = set() |
310 | 310 | for p in self.parent_iter(): |
311 | 311 | for ace in p.acl: |
312 | - if ace.permission == name and ace.access == ACE.alllow: | |
312 | + if ace.permission == name and ace.access == ACE.allow: | |
313 | 313 | roles.add(ace.role_id) |
314 | 314 | return list(roles) |
315 | 315 |
@@ -226,6 +226,23 @@ def test_projects_macro(): | ||
226 | 226 | r = g.markdown_wiki.convert('[[projects display_mode=list show_download_button=False]]') |
227 | 227 | assert 'download-button' not in r |
228 | 228 | |
229 | +@with_setup(setUp) | |
230 | +def test_myprojects_macro(): | |
231 | + h.set_context('test', 'wiki', neighborhood='Projects') | |
232 | + | |
233 | + r = g.markdown_wiki.convert('[[my_projects]]') | |
234 | + for p in c.user.my_projects(): | |
235 | + if p.neighborhood.name == 'Projects': | |
236 | + proj_title = '<h2><a href="%s">%s</a></h2>' % (p.url(), p.name) | |
237 | + assert proj_title in r | |
238 | + | |
239 | + h.set_context('u/test-user-1', 'wiki', neighborhood='Users') | |
240 | + user = M.User.query.get(username='test-user-1') | |
241 | + r = g.markdown_wiki.convert('[[my_projects]]') | |
242 | + for p in user.my_projects(): | |
243 | + proj_title = '<h2><a href="%s">%s</a></h2>' % (p.url(), p.name) | |
244 | + assert proj_title in r | |
245 | + | |
229 | 246 | def get_project_names(r): |
230 | 247 | """ |
231 | 248 | Extracts a list of project names from a wiki page HTML. |