Alessandro Molina avatar Alessandro Molina committed 25c8c80

Few improvements to tags management

Comments (0)

Files changed (5)

smallpress/controllers/root.py

 from smallpress.lib.forms import ArticleForm, UploadForm
 from tgext.datahelpers.validators import SQLAEntityConverter
 from tgext.datahelpers.fields import AttachedFile
-
+from tgext.pluggable import plug_url
+from webhelpers.html.builder import HTML
 from tw.api import CSSLink
 from tw.forms import DataGrid
 from tw.forms.validators import UnicodeString
 article_form = ArticleForm()
 upload_form = UploadForm()
 articles_table = DataGrid(fields=[(l_('Actions'), lambda row:link_buttons(row, 'edit', 'delete', 'hide', 'publish')),
-                                  (l_('Title'), 'title'),
+                                  (l_('Title'), lambda row:HTML.a(row.title,
+                                                                  href=plug_url('smallpress', '/view/%s'%row.uid,
+                                                                                lazy=True))),
                                   (l_('Tags'), comma_separated_tags),
                                   (l_('Author'), 'author'),
                                   (l_('Publishing'), lambda row:format_published(row) + ', ' + format_date(row))])
     @expose('genshi:smallpress.templates.index')
     def index(self, *args, **kw):
         articles = Article.get_published().all()
-        tags = Tagging.tag_cloud_for_set(Article, articles)
+        tags = Tagging.tag_cloud_for_set(Article, articles).all()
         return dict(articles=articles, tags=tags)
 
     @expose('genshi:smallpress.templates.article')
     @validate(dict(article=SQLAEntityConverter(Article)), error_handler=index)
     def view(self, article):
+        visible = False
+
+        if article.published and article.publish_date <= datetime.now():
+            visible = True
+        elif request.identity and article.author == request.identity['user']:
+            visible = True
+        elif request.identity and 'smallpress' in request.identity['groups']:
+            visible = True
+
+        if not visible:
+            return redirect(plug_url('smallpress', '/'))
+
         return dict(article=article)
 
     @require(predicates.in_group('smallpress'))
     @expose()
     def rmattachment(self, attachment):
         article = attachment.article
-        os.unlink(attachment.content.local_path)
         DBSession.delete(attachment)
         flash(_('Attachment successfully removed'))
         return redirect(self.mount_point+'/edit/%s'%article.uid)
             if len(found):
                 articles = Article.get_published().filter(Article.uid.in_([e['uid'] for e in found])).all()
 
-        tags = Tagging.tag_cloud_for_set(Article)
+        tags = Tagging.tag_cloud_for_set(Article).all()
         return dict(articles=articles, tags=tags)

smallpress/model/models.py

 from sqlalchemy.orm import backref, relation
 from sqlalchemy import event
 
+import os
 from datetime import datetime
 from smallpress.model import DeclarativeBase, DBSession
 from tgext.pluggable import app_model, primary_key
         obj.refresh_whoosh(False)
 
     @staticmethod
+    def before_delete(mapper, connection, obj):
+        from smallpress.model import Tagging
+        DBSession.query(Tagging).filter(Tagging.taggable_type == 'Article')\
+                                .filter(Tagging.taggable_id == obj.uid).delete()
+
+    @staticmethod
     def get_published():
         now = datetime.now()
         articles = DBSession.query(Article).filter_by(published=True)\
 
 event.listen(Article, 'after_update', Article.after_update)
 event.listen(Article, 'after_insert', Article.after_insert)
+event.listen(Article, 'before_delete', Article.before_delete)
 
 class Attachment(DeclarativeBase):
     __tablename__ = 'smallpress_attachments'
     article_id = Column(Integer, ForeignKey(Article.uid))
     article = relation(Article, backref=backref('attachments', cascade='all, delete-orphan'))
 
+    @staticmethod
+    def delete_file(mapper, connection, obj):
+        try:
+            os.unlink(obj.content.local_path)
+        except:
+            pass
+
     @property
     def url(self):
-        return self.content.url
+        return self.content.url
+
+event.listen(Attachment, 'before_delete', Attachment.delete_file)

smallpress/partials.py

 @expose('genshi:smallpress.templates.tagcloud')
 def tagcloud(tags=None):
     tagcloud=TagCloud(tagging_url=plug_url('smallpress', '/tagging'))
-    if not tags:
-        tags = Tagging.tag_cloud_for_set(Article)
+    if tags is None:
+        tags = Tagging.tag_cloud_for_set(Article).all()
     return dict(tagcloud=tagcloud, tags=tags)
 
 @expose('genshi:smallpress.templates.search')

smallpress/templates/index.html

         </div>
     </div>
     <div id="smallpress_articles_box">
+        <div py:if="request.identity and 'smallpress' in request.identity['groups']">
+            <a href="${h.plug_url('smallpress', '/manage')}">manage articles</a>
+        </div>
         <div>${h.call_partial('smallpress.partials:articles', articles=articles)}</div>
     </div>
     <div style="clear:right;"></div>

smallpress/templates/tagcloud.html

-<div id="smallpress_tags">
+<div xmlns:py="http://genshi.edgewall.org/"
+     id="smallpress_tags">
     <h3>Tags</h3>
-    ${tagcloud(tags)}
+    <py:if test="tags">
+        ${tagcloud(tags)}
+    </py:if>
 </div>
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.