Commit 805e2d63 by Brandon DeRosier

Add gitlog pagination with django Paginator

parent 4b6c62a8
...@@ -15,6 +15,7 @@ from django.contrib.auth import authenticate ...@@ -15,6 +15,7 @@ from django.contrib.auth import authenticate
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
from django.db import IntegrityError from django.db import IntegrityError
from django.http import HttpResponse, Http404 from django.http import HttpResponse, Http404
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
...@@ -684,6 +685,8 @@ class GitLogs(TemplateView): ...@@ -684,6 +685,8 @@ class GitLogs(TemplateView):
if course_id: if course_id:
course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id) course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id)
page_size = 10
# Set mongodb defaults even if it isn't defined in settings # Set mongodb defaults even if it isn't defined in settings
mongo_db = { mongo_db = {
'host': 'localhost', 'host': 'localhost',
...@@ -715,7 +718,7 @@ class GitLogs(TemplateView): ...@@ -715,7 +718,7 @@ class GitLogs(TemplateView):
# Require staff if not going to specific course # Require staff if not going to specific course
if not request.user.is_staff: if not request.user.is_staff:
raise Http404 raise Http404
cilset = CourseImportLog.objects.all().order_by('-created') cilset = CourseImportLog.objects.order_by('-created')
else: else:
try: try:
course = get_course_by_id(course_id) course = get_course_by_id(course_id)
...@@ -729,11 +732,27 @@ class GitLogs(TemplateView): ...@@ -729,11 +732,27 @@ class GitLogs(TemplateView):
CourseStaffRole(course.id).has_user(request.user)): CourseStaffRole(course.id).has_user(request.user)):
raise Http404 raise Http404
log.debug('course_id={0}'.format(course_id)) log.debug('course_id={0}'.format(course_id))
cilset = CourseImportLog.objects.filter(course_id=course_id).order_by('-created') cilset = CourseImportLog.objects.filter(
course_id=course_id
).order_by('-created')
log.debug('cilset length={0}'.format(len(cilset))) log.debug('cilset length={0}'.format(len(cilset)))
# Paginate the query set
paginator = Paginator(cilset, page_size)
try:
logs = paginator.page(request.GET.get('page'))
except PageNotAnInteger:
logs = paginator.page(1)
except EmptyPage:
# If the page is too high
logs = paginator.page(paginator.num_pages)
mdb.disconnect() mdb.disconnect()
context = {'cilset': cilset, context = {
'course_id': course_id.to_deprecated_string() if course_id else None, 'logs': logs,
'error_msg': error_msg} 'course_id': course_id.to_deprecated_string() if course_id else None,
'error_msg': error_msg,
'page_size': page_size
}
return render_to_response(self.template_name, context) return render_to_response(self.template_name, context)
...@@ -582,6 +582,34 @@ class TestSysAdminMongoCourseImport(SysadminBaseTestCase): ...@@ -582,6 +582,34 @@ class TestSysAdminMongoCourseImport(SysadminBaseTestCase):
self._rm_edx4edx() self._rm_edx4edx()
def test_gitlog_pagination_out_of_range_invalid(self):
"""
Make sure the pagination behaves properly when the requested page is out
of range.
"""
self._setstaff_login()
self._mkdir(getattr(settings, 'GIT_REPO_DIR'))
self._add_edx4edx()
for page in [-1, 0, 1, 2, 'abc']:
# Test the page parameter in various different ways
response = self.client.get(
'{}?page={}'.format(
reverse('gitlogs_detail', kwargs={
'course_id': 'MITx/edx4edx/edx4edx'
}),
page
)
)
self.assertIn(
'Page 1 of 1',
response.content
)
self._rm_edx4edx()
def test_gitlog_courseteam_access(self): def test_gitlog_courseteam_access(self):
""" """
Ensure course team users are allowed to access only their own course. Ensure course team users are allowed to access only their own course.
......
...@@ -30,6 +30,28 @@ ...@@ -30,6 +30,28 @@
}); });
</script> </script>
</%block> </%block>
<%def name="pagination()">
<div class="pagination">
%if logs.has_previous():
<span class="previous-page">
<a href="?page=${logs.previous_page_number()}">
${_("previous")}
</a>
</span>
%endif
${_("Page {current_page} of {total_pages}".format(
current_page=logs.number,
total_pages=logs.paginator.num_pages
))}
%if logs.has_next():
<span class="next-page">
<a href="?page=${logs.next_page_number()}">
${_("next")}
</a>
</span>
%endif
</div>
</%def>
<style type="text/css"> <style type="text/css">
a.active-section { a.active-section {
color: #551A8B; color: #551A8B;
...@@ -63,6 +85,19 @@ table.stat_table td { ...@@ -63,6 +85,19 @@ table.stat_table td {
display: none; display: none;
} }
.pagination, .page-status {
text-align: center;
padding: 12px 0 12px 0;
}
.pagination .previous-page {
padding-right: 10px;
}
.pagination .next-page {
padding-left: 10px;
}
a.selectedmode { background-color: yellow; } a.selectedmode { background-color: yellow; }
textarea { textarea {
...@@ -102,64 +137,69 @@ textarea { ...@@ -102,64 +137,69 @@ textarea {
%endif %endif
%endif %endif
<table class="stat_table" width="100%"> %if len(logs):
<thead> ${pagination()}
<tr>
<th width="15%">${_('Date')}</th> <table class="stat_table" width="100%">
<th width="15%">${_('Course ID')}</th> <thead>
## Translators: Git is a version-control system; see http://git-scm.com/about
<th>${_('Git Action')}</th>
</tr>
</thead>
<tbody>
<%
if course_id == None:
logs = cilset[:10]
else:
logs = cilset[:5]
cil = None
%>
% for index, cil in enumerate(logs):
<%
# Appropriate datetime string for current locale and timezone
date = get_time_display(cil.created.replace(tzinfo=UTC),
DEFAULT_DATE_TIME_FORMAT, coerce_tz=settings.TIME_ZONE)
%>
<tr> <tr>
<td>${date}</td> <th width="15%">${_('Date')}</th>
<td> <th width="15%">${_('Course ID')}</th>
<a href="${reverse('gitlogs_detail', kwargs={'course_id': unicode(cil.course_id)})}"> ## Translators: Git is a version-control system; see http://git-scm.com/about
${cil.course_id | h} <th>${_('Git Action')}</th>
</a>
</td>
<td>
%if course_id is not None:
<a class="toggle-import-log" data-import-log="${index}" href="#">[ + ]</a>
%endif
${cil.git_log}
</td>
</tr> </tr>
</thead>
## Show the full log of the latest import if viewing logs for a specific course <tbody>
%if course_id is not None: %for index, cil in enumerate(logs):
<tr class="import-log" id="import-log-${index}"> <%
<td colspan="3"> # Appropriate datetime string for current locale and timezone
<pre> date = get_time_display(cil.created.replace(tzinfo=UTC),
${cil.import_log | h} DEFAULT_DATE_TIME_FORMAT, coerce_tz=settings.TIME_ZONE)
</pre> %>
<tr>
<td>${date}</td>
<td>
<a href="${reverse('gitlogs_detail', kwargs={'course_id': unicode(cil.course_id)})}">
${cil.course_id | h}
</a>
</td>
<td>
%if course_id is not None:
<a class="toggle-import-log" data-import-log="${index}" href="#">[ + ]</a>
%endif
${cil.git_log}
</td> </td>
</tr> </tr>
%endif
%endfor ## Show the full log of the latest import if viewing logs for a specific course
</tbody> %if course_id is not None:
</table> <tr class="import-log" id="import-log-${index}">
<td colspan="3">
## If viewing a single course and there are no logs available, let the user know <pre>
%if course_id is not None and cil is None: ${cil.import_log | h}
## Translators: git is a version-control system; see http://git-scm.com/about </pre>
${_('No git import logs have been recorded for this course.')} </td>
</tr>
%endif
%endfor
</tbody>
</table>
${pagination()}
%else:
<div class="page-status">
%if not course_id:
# If viewing all logs there are no logs available, let the user know
## Translators: git is a version-control system; see http://git-scm.com/about
${_('No git import logs have been recorded.')}
%else:
# If viewing a single course and there are no logs available, let the user know
## Translators: git is a version-control system; see http://git-scm.com/about
${_('No git import logs have been recorded for this course.')}
%endif
</div>
%endif %endif
</section> </section>
</div> </div>
</section> </section>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment