[#6431] don't rely on bool(cursor)
* bool(cursor) is not good either
* refactor some attachment methods up to (Versioned)Artifact
* User.withskill len fix
diff --git a/Allura/allura/controllers/project.py b/Allura/allura/controllers/project.py
index a1a952c..e36e52e 100644
--- a/Allura/allura/controllers/project.py
+++ b/Allura/allura/controllers/project.py
@@ -755,9 +755,8 @@
@expose('jinja:allura:templates/awards.html')
def index(self, **kw):
require_access(self.neighborhood, 'admin')
- awards = M.Award.query.find(dict(created_by_neighborhood_id=self.neighborhood._id))
- count = awards.count()
- return dict(awards=awards or [], count=count)
+ awards = M.Award.query.find(dict(created_by_neighborhood_id=self.neighborhood._id)).all()
+ return dict(awards=awards or [], count=len(awards))
@expose('jinja:allura:templates/award_not_found.html')
def not_found(self, **kw):
diff --git a/Allura/allura/controllers/trovecategories.py b/Allura/allura/controllers/trovecategories.py
index 86d4738..9af28c5 100644
--- a/Allura/allura/controllers/trovecategories.py
+++ b/Allura/allura/controllers/trovecategories.py
@@ -132,7 +132,7 @@
redirect(redirecturl)
return
- if len(M.User.withskill(cat)) > 0:
+ if M.User.withskill(cat).count() > 0:
m = "This category is used as a skill by at least a user, "
m = m + "therefore it can't be removed."
flash(m, "error")
diff --git a/Allura/allura/ext/admin/templates/project_tools.html b/Allura/allura/ext/admin/templates/project_tools.html
index 78fb8f1..36f98f5 100644
--- a/Allura/allura/ext/admin/templates/project_tools.html
+++ b/Allura/allura/ext/admin/templates/project_tools.html
@@ -44,7 +44,7 @@
</span>
</div>
<form method="post" action="update_mounts" id="install_form" style="display:none">
- <input type="hidden" name="new.ordinal" value="{{installable_tools|length + c.project.direct_subprojects.count()}}"/>
+ <input type="hidden" name="new.ordinal" value="{{installable_tools|length + c.project.direct_subprojects|length}}"/>
<input type="hidden" name="new.ep_name" class="new_ep_name">
<label class="grid-13">Label</label>
<div class="grid-13"><input type="text" name="new.mount_label" class="new_mount_label"></div>
diff --git a/Allura/allura/model/artifact.py b/Allura/allura/model/artifact.py
index 8753f1e..733f2b0 100644
--- a/Allura/allura/model/artifact.py
+++ b/Allura/allura/model/artifact.py
@@ -409,6 +409,11 @@
fp=fp, artifact_id=self._id, **kw)
return att
+ @LazyProperty
+ def attachments(self):
+ return self.attachment_class().query.find(dict(
+ app_config_id=self.app_config_id, artifact_id=self._id, type='attachment')).all()
+
def delete(self):
"""Delete this Artifact.
@@ -462,6 +467,13 @@
def shorthand_id(self):
return '%s#%s' % (self.original().shorthand_id(), self.version)
+
+ @property
+ def attachments(self):
+ orig = self.original()
+ if not orig:
+ return None
+ return orig.attachments
def __getattr__(self, name):
return getattr(self.data, name)
diff --git a/Allura/allura/model/discuss.py b/Allura/allura/model/discuss.py
index 7f17063..a8cd7a3 100644
--- a/Allura/allura/model/discuss.py
+++ b/Allura/allura/model/discuss.py
@@ -525,10 +525,10 @@
subject = getattr(artifact, 'email_subject', '')
return subject or '(no subject)'
- @property
+ @LazyProperty
def attachments(self):
return self.attachment_class().query.find(dict(
- post_id=self._id, type='attachment'))
+ post_id=self._id, type='attachment')).all()
def add_multiple_attachments(self, file_info):
if isinstance(file_info, list):
diff --git a/Allura/allura/model/project.py b/Allura/allura/model/project.py
index ec39157..cedb82e 100644
--- a/Allura/allura/model/project.py
+++ b/Allura/allura/model/project.py
@@ -583,7 +583,7 @@
@property
def direct_subprojects(self):
- return self.query.find(dict(parent_id=self._id, deleted=False))
+ return self.query.find(dict(parent_id=self._id, deleted=False)).all()
@property
def accolades(self):
diff --git a/Allura/allura/templates/widgets/moderate_posts.html b/Allura/allura/templates/widgets/moderate_posts.html
index e243b9a..25294a3 100644
--- a/Allura/allura/templates/widgets/moderate_posts.html
+++ b/Allura/allura/templates/widgets/moderate_posts.html
@@ -53,7 +53,7 @@
<td>{{author.display_name}} ({{author.username}})</td>
<td>{{post.thread.subject or '(no subject)'}}</td>
<td>{{h.text.truncate(post.text,200)}}</td>
- <td>{{post.attachments.count()}}</td>
+ <td>{{post.attachments|length}}</td>
<td>
{% if c.app.config.tool_name.lower() != 'discussion' %}
<a href="{{post.thread.artifact.url()}}">[{{post.thread.artifact.shorthand_id()}}]</a>
diff --git a/Allura/allura/tests/model/test_discussion.py b/Allura/allura/tests/model/test_discussion.py
index 36731bc..51a13ee 100644
--- a/Allura/allura/tests/model/test_discussion.py
+++ b/Allura/allura/tests/model/test_discussion.py
@@ -149,7 +149,7 @@
p.commit()
assert p.parent is None
assert p.subject == 'Test Thread'
- assert p.attachments.count() == 0
+ assert_equals(p.attachments, [])
assert 'wiki/_discuss' in p.url()
assert p.reply_subject() == 'Re: Test Thread'
assert p.link_text() == p.subject
@@ -222,8 +222,8 @@
test_post = t.post('test post')
test_post.add_multiple_attachments([test_file1, test_file2])
ThreadLocalORMSession.flush_all()
- assert test_post.attachments.count() == 2, test_post.attachments.count()
- attaches = test_post.attachments.all()
+ assert_equals(len(test_post.attachments), 2)
+ attaches = test_post.attachments
assert 'test1.txt' in [attaches[0].filename, attaches[1].filename]
assert 'test2.txt' in [attaches[0].filename, attaches[1].filename]
@@ -239,8 +239,8 @@
test_post = t.post('test post')
test_post.add_attachment(test_file)
ThreadLocalORMSession.flush_all()
- assert test_post.attachments.count() == 1, test_post.attachments.count()
- attach = test_post.attachments.first()
+ assert_equals(len(test_post.attachments), 1)
+ attach = test_post.attachments[0]
assert attach.filename == 'test.txt', attach.filename
assert attach.content_type == 'text/plain', attach.content_type
diff --git a/Allura/allura/tests/model/test_project.py b/Allura/allura/tests/model/test_project.py
index 2cd7892..c346107 100644
--- a/Allura/allura/tests/model/test_project.py
+++ b/Allura/allura/tests/model/test_project.py
@@ -121,7 +121,7 @@
def test_users_and_roles():
p = M.Project.query.get(shortname='test')
- sub = p.direct_subprojects.next()
+ sub = p.direct_subprojects[0]
u = M.User.by_username('test-admin')
assert p.users_with_role('Admin') == [u]
assert p.users_with_role('Admin') == sub.users_with_role('Admin')
diff --git a/ForgeBlog/forgeblog/model/blog.py b/ForgeBlog/forgeblog/model/blog.py
index 2cd16e0..1168fe6 100644
--- a/ForgeBlog/forgeblog/model/blog.py
+++ b/ForgeBlog/forgeblog/model/blog.py
@@ -85,13 +85,6 @@
return g.markdown_wiki.convert(self.data.text)
@property
- def attachments(self):
- orig = self.original()
- if not orig:
- return None
- return orig.attachments
-
- @property
def email_address(self):
orig = self.original()
if not orig:
diff --git a/ForgeImporters/forgeimporters/tests/google/functional/test_tracker.py b/ForgeImporters/forgeimporters/tests/google/functional/test_tracker.py
index ca7c8a5..528c2b6 100644
--- a/ForgeImporters/forgeimporters/tests/google/functional/test_tracker.py
+++ b/ForgeImporters/forgeimporters/tests/google/functional/test_tracker.py
@@ -182,7 +182,7 @@
)
def _assert_attachments(self, actual, *expected):
- self.assertEqual(actual.count(), len(expected))
+ self.assertEqual(len(actual), len(expected))
atts = set((a.filename, a.content_type, a.rfile().read()) for a in actual)
self.assertEqual(atts, set(expected))
diff --git a/ForgeTracker/forgetracker/model/ticket.py b/ForgeTracker/forgetracker/model/ticket.py
index d0b69c2..a55efab 100644
--- a/ForgeTracker/forgetracker/model/ticket.py
+++ b/ForgeTracker/forgetracker/model/ticket.py
@@ -811,11 +811,6 @@
if who in (None, User.anonymous()): return 'nobody'
return who.get_pref('display_name')
- @property
- def attachments(self):
- return TicketAttachment.query.find(dict(
- app_config_id=self.app_config_id, artifact_id=self._id, type='attachment'))
-
def update(self, ticket_form):
# update is not allowed to change the ticket_num
ticket_form.pop('ticket_num', None)
diff --git a/ForgeTracker/forgetracker/templates/tracker/ticket.html b/ForgeTracker/forgetracker/templates/tracker/ticket.html
index f780736..95e40a6 100644
--- a/ForgeTracker/forgetracker/templates/tracker/ticket.html
+++ b/ForgeTracker/forgetracker/templates/tracker/ticket.html
@@ -144,7 +144,7 @@
<div id="ticket_content">
{{g.markdown.convert(ticket.description)|safe}}
{% if ticket.attachments %}
- <strong class="grid-18">{{ticket.attachments.count()}} Attachments</strong>
+ <strong class="grid-18">{{ticket.attachments|length}} Attachments</strong>
<div class="clear">
{% for att in ticket.attachments %}
<div class="attachment_thumb">
diff --git a/ForgeTracker/forgetracker/tests/functional/test_root.py b/ForgeTracker/forgetracker/tests/functional/test_root.py
index 823ec28..9d00bc5 100644
--- a/ForgeTracker/forgetracker/tests/functional/test_root.py
+++ b/ForgeTracker/forgetracker/tests/functional/test_root.py
@@ -560,7 +560,7 @@
'summary':'zzz'
}, upload_files=[upload]).follow()
ticket = tm.Ticket.query.find({'ticket_num':1}).first()
- filename = ticket.attachments.first().filename
+ filename = ticket.attachments[0].filename
uploaded = PIL.Image.open(file_path)
r = self.app.get('/bugs/1/attachment/'+filename)
diff --git a/ForgeTracker/forgetracker/tests/unit/test_ticket_model.py b/ForgeTracker/forgetracker/tests/unit/test_ticket_model.py
index 620abcf..93450d1 100644
--- a/ForgeTracker/forgetracker/tests/unit/test_ticket_model.py
+++ b/ForgeTracker/forgetracker/tests/unit/test_ticket_model.py
@@ -270,7 +270,7 @@
ticket = Ticket.new()
ticket.summary = 'test ticket'
ticket.description = 'test description'
- assert_equal(ticket.attachments.count(), 0)
+ assert_equal(len(ticket.attachments), 0)
f = urllib2.urlopen('file://%s' % __file__)
TicketAttachment.save_attachment('test_ticket_model.py', ResettableStream(f),
artifact_id=ticket._id)
diff --git a/ForgeWiki/forgewiki/model/wiki.py b/ForgeWiki/forgewiki/model/wiki.py
index 0321240..e4da9dc 100644
--- a/ForgeWiki/forgewiki/model/wiki.py
+++ b/ForgeWiki/forgewiki/model/wiki.py
@@ -76,10 +76,6 @@
return g.markdown_wiki.convert(self.data.text)
@property
- def attachments(self):
- return self.original().attachments
-
- @property
def email_address(self):
return self.original().email_address
@@ -161,10 +157,6 @@
text=self.text)
return result
- @property
- def attachments(self):
- return WikiAttachment.query.find(dict(artifact_id=self._id, type='attachment'))
-
@classmethod
def upsert(cls, title, version=None):
"""Update page with `title` or insert new page with that name"""
diff --git a/ForgeWiki/forgewiki/tests/functional/test_root.py b/ForgeWiki/forgewiki/tests/functional/test_root.py
index 3312ed7..a55176f 100644
--- a/ForgeWiki/forgewiki/tests/functional/test_root.py
+++ b/ForgeWiki/forgewiki/tests/functional/test_root.py
@@ -391,7 +391,7 @@
self.app.post('/wiki/TEST/attach', upload_files=[upload])
h.set_context('test', 'wiki', neighborhood='Projects')
page = model.Page.query.find(dict(title='TEST')).first()
- filename = page.attachments.first().filename
+ filename = page.attachments[0].filename
uploaded = PIL.Image.open(file_path)
r = self.app.get('/wiki/TEST/attachment/'+filename)