Commits

Chris Chambers committed 9040dc1 Merge

Merge

Comments (0)

Files changed (7)

             if todo or all:
                 required = {
                     'title':       lambda: post['meta']['title'],
-                    'link':        lambda: post['meta']['url'],
+                    'link':        lambda: post['canon_urls']['abs'],
                     'description': lambda: post['html'],
                 }
                 optional = {
                     'author_name': lambda: post['meta']['author'],
                     'pubdate':     lambda: post['meta']['datetime'],
-                    'unique_id':   lambda: post['meta']['url'],
+                    'unique_id':   lambda: post['canon_urls']['abs'],
                 }
                 kwargs = all_kwargs(required, optional, post)
                 if kwargs:

templates/archives.dhtml

 						<h2>{{ month|month }} {{ year }}</h2>
 						<ol>
 					{% for post in these_posts %}
-							<li><a href="{{ post.meta.url }}"><time datetime="{{ post.meta.datetime|datetime }}">{{ post.meta.datetime|display_date }}</time> {{ post.meta.title }}</a></li>
+							<li><a href="{{ post.canon_urls.rel }}"><time datetime="{{ post.meta.datetime|datetime }}">{{ post.meta.datetime|display_date }}</time> {{ post.meta.title }}</a></li>
 					{% endfor %}
 						</ol>
 					</li>

templates/base.dhtml

 		</div><!--/scripts-->
 	</div><!--/wrap-->
 	<footer>
-		<p>Powered by <a href="http://bitbucket.org/davidchambers/mango">Mango</a>.</p>
+		<p>Powered by <a href="http://mango.io/">Mango</a>.</p>
 	</footer>
 	<!-- Generated by Mango at {{ now|date_and_time }} -->
 </body>

templates/index.dhtml

 	{% for post in posts %}{% if forloop.counter <= 5 %}
 			<article>
 				<header>
-					<h2><a href="{{ post.meta.url }}">{{ post.meta.title|safe }}</a></h2>
+					<h2><a href="{{ post.canon_urls.rel }}">{{ post.meta.title|safe }}</a></h2>
 					<time datetime="{{ post.meta.datetime|datetime }}">{{ post.meta.datetime|display_date }}</time>
 				</header>
 				{{ post.excerpt|safe }}

templates/post.dhtml

 					{% endif %}{% ifequal type 'post' %}
 						<dl>
 							<dt>Short URL</dt>
-							<dd><a href="{{ short_url }}">{{ short_url }}</a></dd>
+							<dd><a href="{{ short_urls.abs }}">{{ short_urls.abs }}</a></dd>
 							<dt>Markdown</dt>
-							<dd><a href="{{ short_url }}m/">{{ short_url }}m/</a></dd>
+							<dd><a href="{{ short_urls.abs }}m/">{{ short_urls.abs }}m/</a></dd>
 						</dl>
 					{% endifequal %}
 					</header>
     Returns a post's short and canonical URLs
     
     >>> path_to_posts = mango.utils.absolute_path_to_posts()
+    >>> setattr(mango.settings, 'BASE_URL', 'http://example.com/')
     >>> setattr(mango.settings, 'SHORT_URL_BASE', 'http://✪df.ws/')
     >>> post_urls(os.path.join(path_to_posts, '01=>my-first-post.text'))
-    (u'http://\u272adf.ws/1/', u'/my-first-post/')
+    ({'abs': u'http://\u272adf.ws/1/', 'rel': u'/1/'}, {'abs': u'http://example.com/my-first-post/', 'rel': u'/my-first-post/'})
     >>> setattr(mango.settings, 'SHORT_URL_BASE', '')
     >>> post_urls(os.path.join(path_to_posts, '01=>my-first-post.text'))
-    (u'/1/', u'/my-first-post/')
+    ({'abs': u'http://example.com/1/', 'rel': u'/1/'}, {'abs': u'http://example.com/my-first-post/', 'rel': u'/my-first-post/'})
     >>> post_urls(os.path.join(path_to_posts,
     ...         'js=>javascript', 'libs=>libraries', 'prototype.js', '$.text'))
-    (u'/js/libs/prototype.js/$/', u'/javascript/libraries/prototype.js/$/')
+    ({'abs': u'http://example.com/js/libs/prototype.js/$/', 'rel': u'/js/libs/prototype.js/$/'}, {'abs': u'http://example.com/javascript/libraries/prototype.js/$/', 'rel': u'/javascript/libraries/prototype.js/$/'})
     """
-    canon_fragments = [u'', u'']    # Is this really a better way of doing it rather than adding /%s/ at the end? CC 7/6/2010
+    canon_fragments = [u'', u'']
     alias_fragments = [u'', u'']
 
     head, tail = os.path.split(os.path.abspath(filepath))
             alias_fragments.insert(1, match.group('alias') or canon)
 
     path_to_posts = absolute_path_to_posts()
-    short_url_base = mango.settings.SHORT_URL_BASE.decode('utf-8').rstrip(u'/')
     base_url = mango.settings.BASE_URL.decode('utf-8').rstrip(u'/')
-    if short_url_base == '':
-        short_url_base = base_url
-    short_url = u'/'.join(alias_fragments).replace(path_to_posts, short_url_base, 1)
-    canon_url = u'/'.join(canon_fragments).replace(path_to_posts, base_url, 1)
+    short_url_base = mango.settings.SHORT_URL_BASE.decode('utf-8').rstrip(u'/') or base_url
 
-    return (short_url, canon_url)
+    short_path = u'/'.join(alias_fragments).replace(path_to_posts, u'', 1)
+    canon_path = u'/'.join(canon_fragments).replace(path_to_posts, u'', 1)
+
+    short_urls = {'rel': short_path, 'abs': short_url_base + short_path}
+    canon_urls = {'rel': canon_path, 'abs': base_url + canon_path}
+
+    return (short_urls, canon_urls)
 
 def posts(path_to_posts=PATH_TO_POSTS):
     """
     >>> these_posts[0]['html']
     u"\\n<p>Welcome to Mango. ... <strong>Congratulations!</strong></p>"
     """
-    
-    ret = cache.get(path_to_posts)  # Won't conflcit with the posts above as this will alwasy be a folder
-    if ret:
-        return ret   #There is no check for modification time, this i sjust always current for 5 min
-    
+
+    posts = cache.get(path_to_posts) # won't conflict with the posts above as this will always be a folder
+    if posts:
+        return posts # there is no check for modification time, this is just always current for 5 minutes
+
     posts = []
     for dirpath, dirnames, filenames in os.walk(path_to_posts):
         filenames[:] = [f for f in filenames if not f.startswith('.')]
             # ignore symlink if it points to a file (post) in same directory
             if absolute_path == os.path.realpath(joined_path):
                 this = parse_file(absolute_path)
-                this['meta']['url'] = post_urls(absolute_path)[1]
+                short_urls, canon_urls = post_urls(absolute_path)
+                this['short_urls'] = short_urls
+                this['canon_urls'] = canon_urls
                 posts.append(this)
 
     dated_posts = [post for post in posts if post['meta'].get('datetime')] # display a post only if it has both a date and a time
 import hashlib
 import os
 import re
+import urllib
 
 import disqus
 
 MESSAGES = {
     'approve': {'do': 'Approve comment', 'done': 'Comment approved.'},
     'delete': {'do': 'Delete comment', 'done': 'Comment deleted.'},
-    'spam': {'do': 'Mark comment as spam', 'done': 'Comment marked as spam.'},
+    'spam': {'do': 'Mark comment as spam (and delete it)', 'done': 'Comment marked as spam and deleted.'},
 }
 
 def redirect(request, path):
                 dsq = disqus.DisqusService(DISQUS_API_VERSION)
                 dsq.login(DISQUS.get('api_key'))
                 forum = get_forum(dsq.get_forum_list())
-                thread = dsq.get_thread_by_url(forum, BASE_URL.rstrip('/') + canon_url)
+                thread = dsq.get_thread_by_url(forum, canon_urls['abs'])
                 if not thread:
-                    thread = dsq.thread_by_identifier(forum, context['meta']['title'], canon_url)['thread']
+                    thread = dsq.thread_by_identifier(forum, context['meta']['title'], canon_urls['rel'])['thread']
 
                 if request.method == 'POST':
                     form = CommentForm(request.POST)
                         message = form.cleaned_data['message']
                         subscribe = form.cleaned_data['subscribe']
 
+                        try:
+                            ip_address = urllib.urlopen('http://www.whatismyip.com/automation/n09230945.asp').readlines()[0]
+                        except:
+                            ip_address = None
+
                         # send request to Disqus
-                        comment = dsq.create_post(forum=forum, thread=thread, message=message,
+                        comment = dsq.create_post(forum, thread, message=message, ip_address=ip_address,
                                 author_name=author_name, author_email=author_email, author_url=author_url)
 
                         # store comment so that it can be displayed to the author even if withheld for moderation
                                     messages['do'], BASE_URL.rstrip('/'), action, query_string)
                             html_content += u'<li><a href="%s/moderate/%s?%s">%s</a></li>' % (
                                     BASE_URL.rstrip('/'), action, convert_html_chars(query_string), messages['do'])
-                        html_content += u'</ul>'
+                        text_content += u'\n\n* Respond: %s/%s/#respond' % (BASE_URL.rstrip('/'), path)
+                        html_content += u'<li><a href="%s/%s/#respond">Respond</a></li></ul>' % (BASE_URL.rstrip('/'), path)
 
                         msg = EmailMultiAlternatives(subject, text_content, author, [utils.primary_author_email()])
                         msg.attach_alternative(html_content, 'text/html')
 
                         return HttpResponseRedirect('redirect/')
 
-                for c in dsq.get_thread_posts(forum, thread, limit=0, exclude='killed'):
+                for c in dsq.get_thread_posts(forum, thread, limit=9999, exclude='killed'):
                     if c.has_been_moderated:
                         comments.append(c)
                 if DISQUS.get('sort') == 'oldest_first':
                     'comments': comments,
                     'form': form,
                     'new_comment': comment,
-                    'short_url': short_url,
+                    'short_urls': short_urls,
                     'thread': thread,
                     'type': 'post' if 'datetime' in context['meta'] else 'page',
                 }, **context_defaults(request))))
         if not found:
             raise Http404
 
-    short_url, canon_url = utils.post_urls(filepath)
+    short_urls, canon_urls = utils.post_urls(filepath)
 
     if is_short:
         if view_source:
-            canon_url += 'm/'
-        return HttpResponseRedirect(canon_url)
+            canon_urls['rel'] += 'm/'
+        return HttpResponseRedirect(canon_urls['rel'])
 
     if os.path.isdir(filepath):
         #TODO - if view_source is true what do we do here?
         return HttpResponse(html)
 
     if os.path.islink(filepath): # symbolic link - must appear before view source
-        short_url, canon_url = utils.post_urls(os.path.realpath(filepath))
-        return HttpResponseRedirect(canon_url)
+        short_urls, canon_urls = utils.post_urls(os.path.realpath(filepath))
+        return HttpResponseRedirect(canon_urls['rel'])
 
     if view_source: # Return the plain text of the Markdown page.
         text = utils.parse_file(filepath, plaintext=True)
     if request.GET.get('api_key') != hashlib.sha1(DISQUS['api_key']).hexdigest():
         return HttpResponseBadRequest('Invalid API key.')
 
+    post_id = request.GET.get('post_id')
     dsq = disqus.DisqusService(DISQUS_API_VERSION)
     dsq.login(DISQUS['api_key'])
-    dsq.moderate_post(request.GET.get('post_id'), 'kill' if action == 'delete' else action)
+
+    if action == 'approve':
+        dsq.moderate_post(post_id, 'approve')
+    else:
+        dsq.moderate_post(post_id, 'kill')
+        if action == 'spam':
+            dsq.moderate_post(post_id, 'spam')
+
     return HttpResponse(MESSAGES[action]['done'], content_type='text/plain; charset=utf-8')