Anonymous avatar Anonymous committed fc04e5d Merge

merge

Comments (0)

Files changed (10)

sitepoet/admin.py

 	query_set.update(status=ENTRY_STATUS_PUBLISHED)
 action_mark_published.short_description = "Change status of selected items to Published"
 
+def action_open_comments(model_admin, request, query_set):
+	query_set.update(allow_comments=COMMENTS_ENABLED)
+action_open_comments.short_description = "Allow comments on the selected items"
+
+def action_close_comments(model_admin, request, query_set):
+	query_set.update(allow_comments=COMMENTS_CLOSED)
+action_close_comments.short_description = "Close comments on the selected items"
+
+def action_disable_comments(model_admin, request, query_set):
+	query_set.update(allow_comments=COMMENTS_DISABLED)
+action_disable_comments.short_description = "Disable and hide comments on the selected items"
 
 ### PAGES ###
 
 
 class PageAdmin(admin.ModelAdmin):
 	form		   = PageForm
-	list_display   = ('title', 'absolute_url', 'visibility', 'status', 'date_created', 'date_modified', 'date_published', 'date_hidden')
+	list_display   = ('title', 'absolute_url', 'visible', 'status', 'date_created', 'date_modified', 'date_published', 'date_hidden')
 	list_editable  = ('status',)
 	list_filter	   = ('date_published', 'date_modified', 'status')
 	date_hierarchy = 'date_published'
 	
 	def absolute_url(self, obj):
 		return obj.get_absolute_url()
-	
-	def visibility(self, obj):
-		f = Page.published.filter(pk=obj.id)
-		return (_("Not Visible"), _("Visible"))[(obj in f)]
 
 admin.site.register(Page, PageAdmin)
 
 	date_hierarchy = 'date_published'
 	search_fields = ('title', '^user__username', 'slug')
 	prepopulated_fields = {"slug": ("title",)}
-	actions = [action_mark_draft, action_mark_published]
+	actions = [action_mark_draft, action_mark_published, action_open_comments, action_close_comments, action_disable_comments]
 	fieldsets = [
 		('',				{'fields': ['user', 'title', 'slug', 'tags', 'section']}),
 		('Content',			{'fields': ['teaser_format', 'teaser', 'content_format', 'content']}),

sitepoet/drupal_support/management/commands/convertdrupal.py

 							else:
 								if verbose: print "** Object has %d comments, but the parent should be item %d" % (c_obj.children.count(), parents[0])
 								break
-						if debug: print "** Suspected parent:", c_obj.title
+						if debug and c_obj: print "** Suspected parent:", c_obj.title
 					
 					# Actually create the comment now
 					c = ThreadedComment(

sitepoet/middleware/__init__.py

-from django.http import HttpResponsePermanentRedirect, HttpResponseRedirect, HttpResponseGone
 from django.conf import settings
-from django.http import Http404
+from django.http import HttpResponsePermanentRedirect, HttpResponseRedirect, HttpResponseGone, Http404
+from django.template import Template, RequestContext, loader
 
-from sitepoet.models import Redirect
+from sitepoet.models import Redirect, Page, Story
 from sitepoet.views import view_page
 
-
 class RedirectionMiddleware(object):
 	def process_response(self, request, response):
 		# If the response found something, return it.
 			# Look for an exact redirect
 			path = request.path
 			paths = [path]
-			# Try without the trailing slash
+			
+			# Also try without the trailing slash if someone tacked it on for us
 			if settings.APPEND_SLASH:
 				paths.append(path[:path.rfind('/')] + path[path.rfind('/')+1:])
+			
 			r = Redirect.objects.get(site__id__exact=settings.SITE_ID, original__in=paths)
+			
+			# If the destination is not visible, let the 404 shine.
+			if hasattr(r.target_object, 'visible') and r.target_object.visible == False:
+				return response
+			
 			# If there's a redirect, process it
 			destination = r.destination()
+			
 			# If we're about to tell someone to go where we already are, stop and think...
 			if destination == request.path_info:
 				return response
+			
 			if destination == None:
 				# No destination means it's been removed, so make it a dead end.
-				# 410 Gone
-				#FIXME: We need to return a stock error template here.
-				return HttpResponseGone()
+				context = RequestContext(request, {
+					'title':'410 Gone',
+					'content':'the resource you seek / has been taken by time / seek answers within'
+				})
+				template = loader.get_template("error.html")
+				return HttpResponseGone(template.render(context))
+			
+			if r.permanent == True:
+				# 301 Moved
+				return HttpResponsePermanentRedirect(destination)
 			else:
-				if r.permanent == True:
-					# 301 Moved
-					return HttpResponsePermanentRedirect(destination)
-				else:
-					# 302 Found
-					return HttpResponseRedirect(destination)
+				# 302 Found
+				return HttpResponseRedirect(destination)
+		
 		except Redirect.DoesNotExist, e:
 			# Otherwise, return the original response
 			return response

sitepoet/models.py

 	class Meta:
 		abstract = True
 	
+	@property
+	def visible(self):
+		return (self.status == ENTRY_STATUS_PUBLISHED and self.date_published < datetime.datetime.now())
+	
 	def __init__(self, *args, **kwargs):
 		super(Resource, self).__init__(*args, **kwargs)
 		if self.id != None:

sitepoet/templates/error.html

+{% extends "base.html" %}
+{% block content %}
+<h1>{{title}}</h1>
+
+<p>{{content}}</p>
+{% endblock %}

sitepoet/templates/story.html

     <p class="body">
         {{object.formatted_content}}
     </p>
+	<p class="post-info">
+		{% load tagging_tags %}
+		{% tags_for_object object as tags %}
+		<p /><span class="tags"><span class="post-item-key">Tags:</span> <span class="post-item-value">{% for tag in tags %}<a href="{% url tag tag.name %}">{{tag}}</a>{% if not forloop.last %}, {% endif %}{% endfor %}</span></span></p>
+	</p>
 {% endif %}
 </div>

sitepoet/templates/story_archive.html

 {% load pager %}
 {% block content %}
 <div class="story-list">
-{% for object in list.object_list %}
+{% for object in page.object_list %}
 {% include "story.html" %}
 {% endfor %}
 </div>

sitepoet/templates/tag_cloud.html

+{% load tagging_tags %}
+{% tag_cloud_for_model sitepoet.Story as tag_cloud with min_count=10 steps=5 %}
+<div class="cloud" style="width: 300px">{%for tag in tag_cloud%}
+	<span class="tag" style="font-size:{{tag.font_size}}ex; white-space: nowrap;"><a href="{% url tag tag.name %}">{{tag.name}}</a></span>{%endfor%}
+</div>
 		kwargs = { "teasers": True },
 		name   = "story-archive"
 	),
+	
+	# Tags
+	url(
+		regex  = r'^tag/([^/]*)/?$',
+		view   = 'view_tag',
+		name   = 'tag',
+	)
 )
 
 urlpatterns += patterns('sitepoet.views',

sitepoet/views.py

 
 from sitepoet.models import *
 
+from tagging.models import Tag, TaggedItem
+from tagging.utils import get_tag_list
 
 ### Stories ###
 
 		"options": {
 			"teasers": teasers
 		},
-		"list": stories_page
+		"page": stories_page
 	}
 	
 	if year and month and day:
 	
 	except Page.DoesNotExist, e:
 		# If there's no trailing slash, and we're using it, then try that URL next.
-		if not url.endswith('/') and settings.APPEND_SLASH:
+		if settings.APPEND_SLASH and not url.endswith('/'):
 			return HttpResponseRedirect("%s/" % request.path_info)
 		
 		# Otherwise, give up.
+		print request.path_info, url
 		raise Http404
 	
 	except Page.MultipleObjectsReturned, e:
 	response = render_to_response(templates, context, context_instance=RequestContext(request))
 	populate_xheaders(request, response, Page, page.id)
 	return response
+
+def view_tag(request, tagname, teasers=True):
+	tags = get_tag_list(tagname)
+	if tags.count() == 0:
+		raise Http404
+	
+	items = TaggedItem.objects.get_intersection_by_model(Story, tags)
+	
+	# Paginate the results
+	page = int(request.GET.get('page', 1))		# Requested page number
+	paginator = Paginator(items.select_related(depth=2), settings.SP_PAGE_SIZE)
+	
+	try:
+		stories_page = paginator.page(page)
+	except (EmptyPage, InvalidPage):
+		stories_page = paginator.page(paginator.num_pages)
+	
+	context = {
+		"title": "Stories tagged %s" % tagname,
+		"options": {
+			"teasers": teasers
+		},
+		"page": stories_page,
+	}
+	
+	response = render_to_response("story_archive.html", context, context_instance=RequestContext(request))
+	return response
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.