Skip to content

Commit

Permalink
Merge pull request #17 from peterbe/ability-to-load-all-comments-with…
Browse files Browse the repository at this point in the history
…-ajax

ability to load all comments with ajax
  • Loading branch information
Peter Bengtsson committed Nov 5, 2015
2 parents ed95e76 + 4d8e982 commit 2f53597
Show file tree
Hide file tree
Showing 8 changed files with 130 additions and 76 deletions.
14 changes: 9 additions & 5 deletions .eslintrc
@@ -1,16 +1,20 @@
rules:
indent:
- 2
- 4
- 8
indent: [2, 2]
quotes:
- 2
- 1
- single
linebreak-style:
- 2
- unix
semi:
- 2
- always
comma-dangle:
- 1
- always-multiline
no-extra-semi:
- 1
env:
browser: true
jquery: true
extends: 'eslint:recommended'
2 changes: 1 addition & 1 deletion peterbecom/apps/homepage/views.py
Expand Up @@ -72,7 +72,7 @@ def _home_key_prefixer(request):

@cache_control(public=True, max_age=60 * 60)
@cache_page(
60 * 60,
60 * 60 * 3, # three hours
key_prefix=_home_key_prefixer,
post_process_response=mincss_response
)
Expand Down
1 change: 1 addition & 0 deletions peterbecom/apps/plog/templates/plog/_all_comments.html
@@ -0,0 +1 @@
{{ show_comments(post, user.is_staff, all_comments)|safe }}
18 changes: 12 additions & 6 deletions peterbecom/apps/plog/templates/plog/post.html
Expand Up @@ -76,14 +76,20 @@ <h2 class="ui dividing header">Comments</h2>
{% endif %}
{% else %}
<div id="comments-outer" class="ui comments">
{{ show_comments(post, user.is_staff, all_comments)|safe }}
{% include "plog/_all_comments.html" %}
</div>
{% if comments_truncated %}
<p class="comments-truncated">
Only showing the first {{ comments_truncated }} comments ({{ thousands(post.count_comments()) }} in total).
<br>
<a href="?comments=all" rel="nofollow">Load them all!</a>
</p>
<div class="ui message comments-truncated">
<div class="header">
Comments truncated
</div>
<p>
Only showing the first {{ comments_truncated }} comments
({{ thousands(post.count_comments()) }} in total).
<br>
<button class="ui button">Load them all!</button>
</p>
</div>
{% endif %}

{% endif %}
Expand Down
5 changes: 5 additions & 0 deletions peterbecom/apps/plog/urls.py
Expand Up @@ -26,5 +26,10 @@
url('^(.*)/submit$', views.submit_json, name='submit'),
url('^(.*)/approve/(.*)', views.approve_comment, name='approve_comment'),
url('^(.*)/delete/(.*)', views.delete_comment, name='delete_comment'),
url(
'^(.*)/all-comments$',
views.all_blog_post_comments,
name='all_plog_post_comments'
),
url('^(.*)', views.blog_post, name='blog_post'),
)
73 changes: 52 additions & 21 deletions peterbecom/apps/plog/views.py
Expand Up @@ -53,7 +53,12 @@ def _blog_post_key_prefixer(request):
if request.user.is_authenticated():
return None
prefix = utils.make_prefix(request.GET)
if request.path.endswith('/'):

all_comments = False
if request.path.endswith('/all-comments'):
oid = request.path.split('/')[-2]
all_comments = True
elif request.path.endswith('/'):
oid = request.path.split('/')[-2]
else:
oid = request.path.split('/')[-1]
Expand Down Expand Up @@ -81,29 +86,30 @@ def _blog_post_key_prefixer(request):
cache.set(cache_key, latest_date, ONE_MONTH)
prefix += str(latest_date)

try:
redis_increment('plog:hits', request)
except Exception:
logging.error('Unable to redis.zincrby', exc_info=True)

# temporary solution because I can't get Google Analytics API to work
ua = request.META.get('HTTP_USER_AGENT', '')
if 'bot' not in ua:
# because not so important exactly how many hits each post gets,
# just that some posts are more popular than other, therefore
# we don't need to record this every week.
if random.randint(1, 10) == 1:
# so we only do this sometimes
hits, __ = BlogItemHits.objects.get_or_create(oid=oid)
hits.hits += 1
hits.save()
if not all_comments:
try:
redis_increment('plog:hits', request)
except Exception:
logging.error('Unable to redis.zincrby', exc_info=True)

# temporary solution because I can't get Google Analytics API to work
ua = request.META.get('HTTP_USER_AGENT', '')
if 'bot' not in ua:
# because not so important exactly how many hits each post gets,
# just that some posts are more popular than other, therefore
# we don't need to record this every week.
if random.randint(1, 10) == 1:
# so we only do this sometimes
hits, __ = BlogItemHits.objects.get_or_create(oid=oid)
hits.hits += 1
hits.save()

return prefix


@cache_control(public=True, max_age=60 * 60)
@cache_page(
ONE_DAY, # change this to ONE_WEEK when you know SemanticUI works
ONE_WEEK,
_blog_post_key_prefixer,
post_process_response=mincss_response
)
Expand Down Expand Up @@ -161,9 +167,9 @@ def blog_post(request, oid):

comments_truncated = False
if request.GET.get('comments') != 'all':
comments = comments[:100]
if post.count_comments() > 100:
comments_truncated = 100
comments = comments[:50]
if post.count_comments() > 50:
comments_truncated = 50

all_comments = defaultdict(list)
for comment in comments:
Expand All @@ -179,6 +185,31 @@ def blog_post(request, oid):
return render(request, 'plog/post.html', data)


@cache_control(public=True, max_age=60 * 60)
@cache_page(
ONE_WEEK,
_blog_post_key_prefixer
)
def all_blog_post_comments(request, oid):
post = get_object_or_404(BlogItem, oid=oid)
comments = (
BlogComment.objects
.filter(blogitem=post)
.order_by('add_date')
)
if not request.user.is_staff:
comments = comments.filter(approved=True)

all_comments = defaultdict(list)
for comment in comments:
all_comments[comment.parent_id].append(comment)
data = {
'post': post,
'all_comments': all_comments
}
return render(request, 'plog/_all_comments.html', data)


def get_related_posts(post):
cache_key = 'related_ids:%s' % post.pk
related_pks = cache.get(cache_key)
Expand Down
1 change: 1 addition & 0 deletions peterbecom/settings/base.py
Expand Up @@ -116,6 +116,7 @@ def COMPRESS_JINJA2_GET_ENVIRONMENT():
'semanticuiform',
'semanticui',
'fancy_cache',
'registration',
)

MIDDLEWARE_CLASSES = (
Expand Down
92 changes: 49 additions & 43 deletions peterbecom/static/js/blogitem.js
Expand Up @@ -14,49 +14,49 @@ var F = (function() {
F.prepare();
}
return {
name: $('input[name="name"]', form).val(),
email: $('input[name="email"]', form).val(),
parent: $('input[name="parent"]', form).val(),
comment: $('textarea', form).val(),
csrfmiddlewaretoken: $('input[name="csrfmiddlewaretoken"]', form).val()
name: $('input[name="name"]', form).val(),
email: $('input[name="email"]', form).val(),
parent: $('input[name="parent"]', form).val(),
comment: $('textarea', form).val(),
csrfmiddlewaretoken: $('input[name="csrfmiddlewaretoken"]', form).val(),
};
}

return {
prepare: function(callback) {
if (preparing) {
return; // to avoid excessive calls
}
preparing = true;
$.getJSON('/plog/prepare.json', function(response) {
$('input[name="csrfmiddlewaretoken"]', form).val(response.csrf_token);
if (response.name && !$('input[name="name"]', form).val()) {
$('input[name="name"]', form).val(response.name);
} else {
var name = localStorage.getItem('name');
if (name) {
$('input[name="name"]', form).val(name);
}
}
if (response.email && !$('input[name="email"]', form).val()) {
$('input[name="email"]', form).val(response.email);
} else {
var email = localStorage.getItem('email');
if (email) {
$('input[name="email"]', form).val(email);
}
}

preparing = false;
if (callback) {
callback();
}
});
},
prepare: function(callback) {
if (preparing) {
return; // to avoid excessive calls
}
preparing = true;
$.getJSON('/plog/prepare.json', function(response) {
$('input[name="csrfmiddlewaretoken"]', form).val(response.csrf_token);
if (response.name && !$('input[name="name"]', form).val()) {
$('input[name="name"]', form).val(response.name);
} else {
var name = localStorage.getItem('name');
if (name) {
$('input[name="name"]', form).val(name);
}
}
if (response.email && !$('input[name="email"]', form).val()) {
$('input[name="email"]', form).val(response.email);
} else {
var email = localStorage.getItem('email');
if (email) {
$('input[name="email"]', form).val(email);
}
}

preparing = false;
if (callback) {
callback();
}
});
},
setupReply: function(parent) {
preparing = false;
if (parent.size() !== 1) {
throw new Error("Must be exactly 1 parent");
throw new Error('Must be exactly 1 parent');
}
form.detach().insertAfter($('.text:eq(0)', parent));
preview.detach().insertBefore(form);
Expand Down Expand Up @@ -88,7 +88,7 @@ var F = (function() {
}

$.ajax({
url: '/plog/preview.json',
url: '/plog/preview.json',
data: data,
type: 'POST',
dataType: 'json',
Expand All @@ -101,7 +101,7 @@ var F = (function() {
},
error: function (jqXHR, textStatus, errorThrown) {
alert('Error: ' + errorThrown);
}
},
});
},
submit: function() {
Expand Down Expand Up @@ -161,10 +161,10 @@ var F = (function() {
form.css('opacity', 1);
alert('Error: ' + errorThrown);
submitting = false;
}
},
});
return false;
}
},
};
})();

Expand All @@ -175,13 +175,11 @@ $(function() {
var form = $('form#comment');

form.on('mouseover', function() {
// $(window).off('scroll');
$(this).off('mouseover');
F.prepare();
});

form.on('mouseover', function() {
// $(window).off('scroll');
$(this).off('mouseover');
F.prepare();
});
Expand Down Expand Up @@ -223,11 +221,19 @@ $(function() {
var oid = $(this).data('oid');
var url = location.pathname;
url += '/delete/' + oid;
var button = $(this);
$.post(url, {csrfmiddlewaretoken: $('input[name="csrfmiddlewaretoken"]').val()}, function() {
$('#' + oid).remove();
});
return false;
});

var loadingAllComments = false; // for the slow-load lock
$('.comments-truncated').on('click', 'button', function() {
if (loadingAllComments) return;
loadingAllComments = true;
$('#comments-outer').load(location.pathname + '/all-comments', function() {
$('.comments-truncated').remove();
});
});

});

0 comments on commit 2f53597

Please sign in to comment.