Added a top level Comments tab

[email protected]
Newsgroups gmane.comp.python.zope.coreblog.english
Message-ID <[email protected]>
I got sick of drilling down through entries to find all of the comment
spam so I created myself a Comments tab that shows all of the comments
in the entire blog.  The link to editting the comment doesn't work yet,
but I can delete and moderate comments now.

Here is the patch in case anyone else finds this useful.
I worked against COREBlog 1.2 (or somewhere around there).

Nate

Index: COREBlog.py
===================================================================
--- COREBlog.py	(revision 43)
+++ COREBlog.py	(working copy)
@@ -118,6 +118,7 @@
     manage_options=( \
                 {'label':'Entries', 'icon':'', 'action':'manage_entryForm', 'target':'manage_main',
                  'help': ('COREBlog', 'Entries.stx') },
+		{'label':'Comments', 'icon':'', 'action':'manage_commentsForm', 'target':'manage_main'},
                 {'label':'Contents', 'icon':icon, 'action':'manage_main', 
                  'target':'manage_main','help': ('COREBlog', 'Contents.stx') },
                 {'label':'View', 'icon':'', 'action':'index_html', 'target':'manage_main'},     
@@ -167,6 +168,8 @@
     #security.declareProtected(ManageCOREBlog, 'manage_editSkinsettingForm')
     #manage_editSkinsettingForm = HTMLFile('dtml/manage_editSkinsettingForm',globals())
 
+    security.declareProtected(ManageCOREBlog, 'manage_commentsForm')
+    manage_commentsForm = HTMLFile('dtml/manage_listCommentsForm',globals())
     #CSS
     security.declareProtected(ManageCOREBlog, 'additional_css')
     additional_css = HTMLFile('dtml/additional_css',globals())
@@ -661,6 +664,13 @@
         if REQUEST is not None:
             return REQUEST.RESPONSE.redirect(REQUEST['HTTP_REFERER'])
 
+    security.declareProtected(ManageCOREBlog, 'recatalogComments')
+    def recatalogComments(self,REQUEST=None):
+        """ Recatalog all Entry Comments """
+        for obj in self.entry_items():
+            obj.check_comment_ids()
+        if REQUEST is not None:
+            return REQUEST.RESPONSE.redirect(REQUEST['HTTP_REFERER'])
 
     #Listing
 
@@ -942,6 +952,10 @@
         """Return count of Entry."""
         return len(self.entries)
 
+    security.declareProtected(View, 'count_comments')
+    def count_comments(self):
+    	"""Return count of Comments."""
+	return len(self.comments)
 
     security.declarePrivate('getNewEntryID')
     def getNewEntryID(self):
@@ -1066,6 +1080,21 @@
         self.comments[id] = obj
 
 
+    security.declareProtected(ManageCOREBlog, 'deleteComments')
+    def deleteComments(self,ids,REQUEST=None):
+    	""" Delete comments in ids """
+	if type(ids) != ListType:
+	    raise TypeError, "Parameter 'ids' must be a ListType."
+	ids = map(lambda x: int(x), ids)
+	ids.sort()
+	ids.reverse()
+	for id in ids:
+	    self.deleteComment(id)
+	for entry in self.entry_items():
+		entry.check_comment_ids(ids)
+        if REQUEST is not None:
+            return REQUEST.RESPONSE.redirect(REQUEST['HTTP_REFERER'])
+
     security.declarePrivate('deleteComment')
     def deleteComment(self,id):
         #Delete a Comment object from self.comments
@@ -1092,24 +1121,23 @@
 
 
     security.declareProtected(View, 'rev_comment_items')
-    def rev_comment_items(self,start=0,count=-1):
+    def rev_comment_items(self,start=0,count=-1,consider_moderation = 1):
         """Return list of Comment(reversed indexing)."""
         start = r2i(start,0)
         count = r2i(count,-1)
+	consider_moderation = r2i(consider_moderation,1)
         l = []
         if count == -1:
             count = len(self.comment_list)
         l_e = len(self.comment_list) - 1
-        while count > 0:
-            if l_e < 0:
+	for c in range(start,start+count):
+            if l_e < c:
                 #index out of range
                 break
-            id = self.comment_list[l_e]
+            id = self.comment_list[l_e - c]
             obj = self.getComment(id)
-            l_e = l_e - 1
-            if obj.moderated:
+            if (not consider_moderation) or obj.moderated:
                 l.append(obj)
-                count = count - 1
         return l
 
 
Index: Entry.py
===================================================================
--- Entry.py	(revision 43)
+++ Entry.py	(working copy)
@@ -733,6 +733,21 @@
         #Return count of moderated comments
         return self.moderated_comment_count
 
+    security.declareProtected(ManageCOREBlog, 'check_comment_ids')
+    def check_comment_ids(self, checklist=[]):
+    	if len(checklist):
+	    # Check comments against the passed in list
+	    for id in checklist:
+	    	if id in self.comments:
+		    self.deleteComment(id)
+	else:
+	    # Check comments against the parent list
+	    myids = self.comments
+	    for id in myids:
+	        try:
+                    obj = self.blog().getComment(id)
+		except KeyError:
+		    self.deleteComment(id)
 
     #
     # Trackback management
Index: dtml/manage_listCommentsForm.dtml
===================================================================
--- dtml/manage_listCommentsForm.dtml	(revision 0)
+++ dtml/manage_listCommentsForm.dtml	(revision 44)
@@ -0,0 +1,160 @@
+<dtml-comment>
+manage_listCommentsForm.html
+
+Interface for showing all comments of all entries
+
+Copyright (c) 2006 Nathan Straz
+</dtml-comment>
+
+<dtml-var manage_page_header>
+<dtml-var manage_tabs>
+
+<p class="form-help">
+Manage comments for '<dtml-var title>'.
+</p>
+
+<dtml-comment>Set the values</dtml-comment>
+<dtml-unless start>
+<dtml-call "REQUEST.set('start',0)">
+</dtml-unless start>
+<dtml-call "REQUEST.set('count',20)">
+<dtml-call "REQUEST.set('showsize',280)">
+<dtml-call "REQUEST.set('liststart',max(0,start-(showsize/2)))">
+<dtml-call "REQUEST.set('listend',min(count_comments(),liststart+showsize))">
+<dtml-call "REQUEST.set('start',_.int(start))">
+
+<form action="&dtml-URL1;/" name="objectItems" method="post">
+<dtml-if count_comments>
+	<table width="100%" cellspacing="0" cellpadding="2" border="0">
+		<tr>
+			<td colspan="8" align="right">
+			<dtml-if "start !=0">
+			<a href="./manage_commentsForm?start:int=<dtml-var "start - count">">Prev</a>&nbsp;
+			</dtml-if>
+			<dtml-if "liststart !=0">
+			<a href="./manage_commentsForm?start:int=<dtml-var "min(0,liststart - count)">">...</a>&nbsp;
+			</dtml-if>
+			<dtml-in "range(liststart,listend,count)">
+			<dtml-call "REQUEST.set('seqitem',_['sequence-item'])">
+			<dtml-if "seqitem <= start and seqitem > start-count">
+			<b>[<dtml-var  "_['sequence-index'] + (liststart/count)+1">]</b>
+			&nbsp;
+			<dtml-else>
+			<a href="./manage_commentsForm?start:int=<dtml-var seqitem>">
+			<dtml-var  "_['sequence-index'] + (liststart/count)+1">
+			</a>&nbsp;
+			</dtml-if>
+			</dtml-in>
+			<dtml-if "listend !=count_comments">
+			<a href="./manage_commentsForm?start:int=<dtml-var "seqitem + count">">...</a>&nbsp;
+			</dtml-if>
+			<dtml-if "count_comments > (start + count)">
+			<a href="./manage_commentsForm?start:int=<dtml-var "start + count">">Next</a>
+			</dtml-if>
+			</td>
+		</tr>
+		<tr class="list-header">
+			<td width="5%" align="left" >Del</td>
+			<td width="45%" align="left" class="list-item"><div class="list-item">Title</div></td>
+			<td width="10%" align="left" class="list-item"><div class="list-item">Author</div></td>
+			<td width="10%" align="left" class="list-item"><div class="list-item">Body</div></td>
+			<td width="25%" align="left" class="list-item"><div class="list-item">Created</div></td>
+			<td width="5%" align="left" >Open</td>
+		</tr>
+		<dtml-in "rev_comment_items(start=start,count=count,consider_moderation=0)">
+		<dtml-var sequence-item>
+		<tr class="<dtml-if sequence-odd>row-normal<dtml-else>row-hilite</dtml-if>">
+			<td align="left" valign="top">
+			<input type="checkbox" name="ids:list" value="<dtml-var id>" /><img src="misc_/COREBlog/comment_img" border="0" alt="comment">
+			</td>
+			<td align="left" valign="top">
+			<div class="list-item">
+			<a href="./manage_editComment?comment_id=<dtml-var id>">
+			<dtml-var title>
+			</a>
+			</div>
+			</td>
+			<td>
+			<div class="list-item">
+			<dtml-var author>
+			</div>
+			</td>
+			<td>
+			<div class="list-item">
+			<dtml-var "_.len(body)">
+			</div>
+			</td>
+			<td>
+			<div class="list-item">
+			<dtml-var date_created fmt="%Y-%m-%d %H:%M">
+			</div>
+			</td>
+			<td align="left" valign="top" width="16">
+			<input type="checkbox" name="mod_ids:list" value="<dtml-var id>" <dtml-if moderated>checked<dtml-else></dtml-if>/>
+			</td>
+		</tr>
+		</dtml-in>
+		<tr>
+		  <td align="left" valign="top" width="16"></td>
+		  <td align="left" valign="top" colspan="3">
+		  <div class="form-element">
+		  <input class="form-element" type="submit" name="deleteComments:method" 
+		   value="Delete" />
+		  </td>
+		  <td align="right" valign="top" colspan="2">
+		  <input class="form-element" type="submit" name="moderateComments:method" 
+		   value="Change Status" />
+		  </div>
+		  </td>
+		</tr>
+		<tr>
+			<td colspan="8" align="right">
+			<dtml-if "start !=0">
+			<a href="./manage_commentsForm?start:int=<dtml-var "start - count">">Prev</a>&nbsp;
+			</dtml-if>
+			<dtml-if "liststart !=0">
+			<a href="./manage_commentsForm?start:int=<dtml-var "min(0,liststart - count)">">...</a>&nbsp;
+			</dtml-if>
+			<dtml-in "range(liststart,listend,count)">
+			<dtml-call "REQUEST.set('seqitem',_['sequence-item'])">
+			<dtml-if "seqitem <= start and seqitem > start-count">
+			<b>[<dtml-var  "_['sequence-index'] + (liststart/count)+1">]</b>
+			&nbsp;
+			<dtml-else>
+			<a href="./manage_commentsForm?start:int=<dtml-var seqitem>">
+			<dtml-var  "_['sequence-index'] + (liststart/count)+1">
+			</a>&nbsp;
+			</dtml-if>
+			</dtml-in>
+			<dtml-if "listend !=count_comments">
+			<a href="./manage_commentsForm?start:int=<dtml-var "seqitem + count">">...</a>&nbsp;
+			</dtml-if>
+			<dtml-if "count_comments > (start + count)">
+			<a href="./manage_commentsForm?start:int=<dtml-var "start + count">">Next</a>
+			</dtml-if>
+			</td>
+		</tr>
+	</table>
+	<table>
+	<tr>
+	<td><div class="form-element">
+	<input class="form-element" type="submit" name="recatalogComments:method" value="Recatalog"/>
+	</div>
+	</tr>
+	</table>
+<dtml-else>
+	<table cellspacing="0" cellpadding="2" border="0">
+		<tr>
+			<td>
+			<div class="std-text">
+			There are currently no entries in <em><dtml-var title></em>
+			<br /><br />
+			</div>
+			</td>
+			</tr>
+	</table>
+</dtml-if>
+
+</form>
+
+<dtml-var manage_page_footer>
_______________________________________________
COREblog-en mailing list
COREblog-en-/9qXvnWia/9Wk0Htik3J/[email protected]
http://postaria.com/cgi-bin/mailman/listinfo/coreblog-en
Unsubscription writing to coreblog-en-leave-/9qXvnWia/9Wk0Htik3J/[email protected]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.