Added pagination to commit list and issue list + changeset page now display categories before and after modifications
authorNicolas DURAND <nicolas.durand@iri.centrepompidou.fr>
Fri, 20 Feb 2015 18:42:52 +0100
changeset 46 5bd3fb023396
parent 45 1506da593f40
child 47 ddba4624d661
Added pagination to commit list and issue list + changeset page now display categories before and after modifications
src/catedit/__init__.py
src/catedit/static/css/style.css
src/catedit/templates/macros.html
src/catedit/templates/social/changeset.html
src/catedit/templates/social/comment_thread_layout.html
src/catedit/templates/social/index.html
src/catedit/views/social.py
src/catedit/views/utils.py
--- a/src/catedit/__init__.py	Fri Feb 20 10:55:54 2015 +0100
+++ b/src/catedit/__init__.py	Fri Feb 20 18:42:52 2015 +0100
@@ -85,6 +85,7 @@
     """
     session["pagination_links"] = {}
     log_api_rate(r, *args, **kwargs)
+    print("link header: "+r.headers.get("link", "none"))
     if r.headers.get("link", None) is not None:
         session["pagination_links"] = r.links
         for (key, item) in session["pagination_links"].items():
@@ -92,32 +93,33 @@
             item["url"] = resource
         if session["pagination_links"].get("next", None) is not None:
             page_arg = re.search(
-                "(\?|&)page=\d",
+                "(\?|&)page=(\d+)",
                 string=session["pagination_links"]["next"]["url"]
             )
             session["pagination_links"]["current_page"] = int(
-                page_arg.group(0)[-1]
+                page_arg.group(2)
             )-1
             if session["pagination_links"].get("last", None) is not None:
                 last_page_arg = re.search(
-                    "(\?|&)page=\d",
+                    "(\?|&)page=(\d+)",
                     string=session["pagination_links"]["last"]["url"]
                 )
                 session["pagination_links"]["last_page"] = int(
-                    page_arg.group(0)[-1]
+                    last_page_arg.group(2)
                 )
             else:
                 # We don't know what is the last page (case: github commits
                 # API)
-                session["pagination_links"]["last_page"] = -1
+                session["pagination_links"]["last_page"] = \
+                session["pagination_links"]["current_page"] + 1
         elif session["pagination_links"].get("prev", None) is not None:
             # This means we're at the last page
             page_arg = re.search(
-                "(\?|&)page=\d",
+                "(\?|&)page=(\d+)",
                 string=session["pagination_links"]["prev"]["url"]
             )
             session["pagination_links"]["current_page"] = int(
-                page_arg.group(0)[-1]
+                page_arg.group(2)
             )+1
             session["pagination_links"] \
                    ["last_page"] = session["pagination_links"]["current_page"]
@@ -151,15 +153,20 @@
                  endpoint='category_changes')
 
 # Pagination utility functions for templates
-def url_for_other_page(page):
+def url_for_other_page(page, arg_name="page"):
     args = request.view_args.copy()
-    args['page'] = page
+    args[arg_name] = page
     return url_for(request.endpoint, **args)
 app.jinja_env.globals['url_for_other_page'] = url_for_other_page
 
-def url_for_other_per_page(per_page):
+def url_for_other_per_page(
+    per_page,
+    page_arg_name="page",
+    per_page_arg_name="per_page"
+):
     args = request.view_args.copy()
-    args['per_page'] = per_page
+    args[page_arg_name] = 1
+    args[per_page_arg_name] = per_page
     return url_for(request.endpoint, **args)
 app.jinja_env.globals['url_for_other_per_page'] = url_for_other_per_page
 
--- a/src/catedit/static/css/style.css	Fri Feb 20 10:55:54 2015 +0100
+++ b/src/catedit/static/css/style.css	Fri Feb 20 18:42:52 2015 +0100
@@ -50,6 +50,15 @@
   color: white !important;
 }
 
+p.text-justified{
+  text-align: justify;
+}
+
+.changeset-menu
+{
+  display: block;
+}
+
 .footer-notes
 {
   padding-right: 40px;
--- a/src/catedit/templates/macros.html	Fri Feb 20 10:55:54 2015 +0100
+++ b/src/catedit/templates/macros.html	Fri Feb 20 18:42:52 2015 +0100
@@ -103,16 +103,16 @@
   {% endfor %}
 {%- endmacro %}
 
-{% macro render_pagination(pagination) -%}
+{% macro render_pagination(pagination, per_page, page_arg_name="page", per_page_arg_name="per_page") -%}
   {% if pagination %}
     <ul class="pagination">
     {% if pagination.has_prev %}
-      <li><a href="{{ url_for_other_page(pagination.page - 1)}}" aria-label="Previous">&laquo;</a></li>
+      <li><a href="{{ url_for_other_page(pagination.page - 1, page_arg_name)}}" aria-label="Previous">&laquo;</a></li>
     {% endif %}
     {% for page in pagination.iter_pages() %}
       {% if page %}
         {% if page != pagination.page %}
-          <li><a href="{{ url_for_other_page(page) }}">{{ page }}</a></li>
+          <li><a href="{{ url_for_other_page(page, page_arg_name) }}">{{ page }}</a></li>
         {% else %}
           <li class="active"><a>{{ page }}</a></li>
         {% endif %}
@@ -121,16 +121,16 @@
       {% endif %}
     {% endfor %}
     {% if pagination.has_next %}
-      <li><a href="{{ url_for_other_page(pagination.page + 1)}}" aria-label="Next">&raquo;</a></li>
+      <li><a href="{{ url_for_other_page(pagination.page + 1, page_arg_name)}}" aria-label="Next">&raquo;</a></li>
     {% endif %}
     </ul>
-    <form class="form form-inline form-pagination">
-      <label class="label-pagination">Commentaires par page:</label>
-      <select class="form-control" name="comment_count" onchange="window.location.href=this.form.comment_count.options[this.form.comment_count.selectedIndex].value">
-        {% for count in [10, 30, 50, 100] %}
-          <option value="{{url_for_other_per_page(count)}}" {% if pagination.per_page==count %}selected="selected"{% endif %}>{{count}}</option>
-        {% endfor %}
-      </select>
-    </form>
   {% endif %}
+  <form class="form form-inline form-pagination">
+    <label class="label-pagination">Par page:</label>
+    <select class="form-control" name="comment_count" onchange="window.location.href=this.form.comment_count.options[this.form.comment_count.selectedIndex].value">
+      {% for count in [10, 30, 50, 100] %}
+        <option value="{{url_for_other_per_page(count, per_page_arg_name, per_page_arg_name)}}" {% if per_page==count %}selected="selected"{% endif %}>{{count}}</option>
+      {% endfor %}
+    </select>
+  </form>
 {%- endmacro %}
--- a/src/catedit/templates/social/changeset.html	Fri Feb 20 10:55:54 2015 +0100
+++ b/src/catedit/templates/social/changeset.html	Fri Feb 20 18:42:52 2015 +0100
@@ -11,17 +11,77 @@
   <script>
     $(document).ready(function(){
       $(".cat-info-div").hide();
-      $(".cat-table-toggle").click(function(evt){
-        $(".cat-table").slideToggle(function(){
-          $(".cat-table-toggle").children().toggleClass("glyphicon-chevron-up");
-          $(".cat-table-toggle").children().toggleClass("glyphicon-chevron-down");
+      $(".cat-table").hide();
+
+      $(".before-cat-table-toggle").click(function(evt){
+        $(".before-cat-table-toggle").toggleClass("btn-info")
+        $(".before-box").toggleClass("alert-info");
+
+        $(".after-cat-table-toggle").removeClass("btn-info")
+        $(".after-box").removeClass("alert-info");
+
+        $(".changes-table-toggle").removeClass("btn-info")
+        $(".changes-box").removeClass("alert-info");
+
+        $(".before-cat-table").slideToggle(function(){
+          $(".before-cat-table-toggle").children().toggleClass("glyphicon-chevron-up glyphicon-chevron-down")
+        });
+        $(".after-cat-table").slideUp(function(){
+          $(".after-cat-table-toggle").children().removeClass("glyphicon-chevron-up").addClass("glyphicon-chevron-down");
+        });
+        $(".changes-table").slideUp(function(){
+          $(".changes-table-toggle").children().removeClass("glyphicon-chevron-up").addClass("glyphicon-chevron-down");
         });
       });
+
+      $(".after-cat-table-toggle").click(function(evt){
+        $(".after-cat-table-toggle").toggleClass("btn-info")
+        $(".after-box").toggleClass("alert-info");
+
+        $(".before-cat-table-toggle").removeClass("btn-info")
+        $(".before-box").removeClass("alert-info");
+
+        $(".changes-table-toggle").removeClass("btn-info")
+        $(".changes-box").removeClass("alert-info");
+
+        $(".after-cat-table").slideToggle(function(){
+          $(".after-cat-table-toggle").children().toggleClass("glyphicon-chevron-up glyphicon-chevron-down")
+        });
+        $(".before-cat-table").slideUp(function(){
+          $(".before-cat-table-toggle").children().removeClass("glyphicon-chevron-up").addClass("glyphicon-chevron-down");
+        });
+        $(".changes-table").slideUp(function(){
+          $(".changes-table-toggle").children().removeClass("glyphicon-chevron-up").addClass("glyphicon-chevron-down");
+        });
+      });
+
+      $(".changes-table-toggle").click(function(evt){
+        $(".changes-table-toggle").toggleClass("btn-info")
+        $(".changes-box").toggleClass("alert-info");
+
+        $(".before-cat-table-toggle").removeClass("btn-info")
+        $(".before-box").removeClass("alert-info");
+
+        $(".after-cat-table-toggle").removeClass("btn-info")
+        $(".after-box").removeClass("alert-info");
+
+        $(".changes-table").slideToggle(function(){
+          $(".changes-table-toggle").children().toggleClass("glyphicon-chevron-up glyphicon-chevron-down")
+        });
+        $(".before-cat-table").slideUp(function(){
+          $(".before-cat-table-toggle").children().removeClass("glyphicon-chevron-up").addClass("glyphicon-chevron-down");
+        });
+        $(".after-cat-table").slideUp(function(){
+          $(".after-cat-table-toggle").children().removeClass("glyphicon-chevron-up").addClass("glyphicon-chevron-down");
+        });
+      });
+
       $(".cat-info-toggle").click(function(evt){
         $("#properties_"+evt.target.id.split('_').slice(2,5).join('_')).slideToggle(function(){
           $("#info_button_"+evt.target.id.split('_').slice(2,5).join('_')).children().toggleClass("glyphicon-plus-sign");
           $("#info_button_"+evt.target.id.split('_').slice(2,5).join('_')).children().toggleClass("glyphicon-minus-sign");
         });
+
       });
     });
   </script>
@@ -32,17 +92,44 @@
   <li class="active"><a>Discussion: changements</a></li>
 {% endblock navbar_items %}
 {% block additional_content %}
-<h3><strong>Etat de l'ensemble des catégories pour ces modifications </strong>
-  <a title="Afficher/Cacher tableau" class="btn btn-default cat-table-toggle">
-    <span class="glyphicon glyphicon-chevron-up"/>
-  </a>
-</h3>
-<div class="cat-table">
+<div class="container changeset-menu">
+  <div class="col-md-4 before-box alert">
+    <h4><strong>Avant modifications </strong>
+    <a title="Afficher/Cacher tableau" class="btn btn-default before-cat-table-toggle">
+      <span class="glyphicon glyphicon-chevron-down"/>
+    </a></h4>
+    <p class="text-justified">
+      Permet de visualiser l'état de l'ensemble de catégories {{current_repository}} avant que ne soient pris en compte
+      les changements considérés.
+    </p>
+  </div>
+  <div class="col-md-4 changes-box alert">
+    <h4><strong>Résumé des modifications </strong>
+    <a title="Afficher/Cacher tableau" class="btn btn-default changes-table-toggle">
+      <span class="glyphicon glyphicon-chevron-down"/>
+    </a></h4>
+    <p class="text-justified">
+      Permet de visualiser les différences entre l'ensemble de catégories {{current_repository}} avant les modifications considérées
+      et le même ensemble après les modifications
+    </p>
+  </div>
+  <div class="col-md-4 after-box alert">
+    <h4><strong>Après modifications </strong>
+    <a title="Afficher/Cacher tableau" class="btn btn-default after-cat-table-toggle">
+      <span class="glyphicon glyphicon-chevron-down"/>
+    </a></h4>
+    <p class="text-justified">
+      Permet de visualiser l'état de l'ensemble de catégories {{current_repository}} après prise en compte
+      les changements considérés.
+    </p>
+  </div>
+</div><br>
+<div class="before-cat-table cat-table">
   <table class="table table-condensed table-bordered">
     <thead>
       <tr class="active">
-        <th class="col-md-2"><b>Nom de la catégorie</b></th>
-        <th class="col-md-10" colspan="2"><b>Description de la catégorie</b></th>
+        <th class="col-md-2"><b>Nom</b></th>
+        <th class="col-md-10" colspan="2"><b>Description</b></th>
       </tr>
     </thead>
     <tbody>
@@ -55,13 +142,52 @@
       </td>
     </tr>
     {% else %}
-      {% if cat_list|length == 0 %}
+      {% if old_cat_list|length == 0 %}
         <tr>
-          <td class="col-md-12" colspan="2">Aucune catégorie n'existait suite à ces changements. {% if not readonly %}<a href="{{ url_for('categories.editor', repository=current_repository) }}">Créer une catégorie</a>{% endif %}</td>
+          <td class="col-md-12" colspan="2">Aucune catégorie n'existait avant ces changements. {% if not readonly %}<a href="{{ url_for('categories.editor', repository=current_repository) }}">Créer une catégorie</a>{% endif %}</td>
         </tr>
       {% else %}
         {% import "macros.html" as macros %}
-        {{ macros.category_table(cat_list, current_repository, state_list=["original"], interactive=False) }}
+        {{ macros.category_table(old_cat_list, current_repository, state_list=["original"], interactive=False) }}
+      {% endif %}
+    {% endif %}
+    </tbody>
+  </table>
+</div>
+<div class="changes-table cat-table">
+  <table class="table table-striped">
+    <tr>
+      <td>
+        placeholder
+      </td>
+    </tr>
+  </table>
+</div>
+<div class="after-cat-table cat-table">
+  <table class="table table-condensed table-bordered">
+    <thead>
+      <tr class="active">
+        <th class="col-md-2"><b>Nom</b></th>
+        <th class="col-md-10" colspan="2"><b>Description</b></th>
+      </tr>
+    </thead>
+    <tbody>
+    {% if not session["user_logged"] %}
+    <tr>
+      <td class="col-md-12" colspan="2">
+        <span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
+        <span class="sr-only">Attention:</span>
+        Veuillez vous identifier pour visualiser les catégories
+      </td>
+    </tr>
+    {% else %}
+      {% if new_cat_list|length == 0 %}
+        <tr>
+          <td class="col-md-12" colspan="2">Aucune catégorie n'existe suite à ces changements. {% if not readonly %}<a href="{{ url_for('categories.editor', repository=current_repository) }}">Créer une catégorie</a>{% endif %}</td>
+        </tr>
+      {% else %}
+        {% import "macros.html" as macros %}
+        {{ macros.category_table(new_cat_list, current_repository, state_list=["modified"], interactive=False) }}
       {% endif %}
     {% endif %}
     </tbody>
--- a/src/catedit/templates/social/comment_thread_layout.html	Fri Feb 20 10:55:54 2015 +0100
+++ b/src/catedit/templates/social/comment_thread_layout.html	Fri Feb 20 18:42:52 2015 +0100
@@ -14,68 +14,69 @@
 {% endblock navbar_items %}
 {% block page_content %}
 <h2> <b>CatEdit</b> - <small>{{current_repository}}</small></h2>
-{% block additional_content %}
-{% endblock additional_content %}
-<h3><strong>Discussion</strong></h3>
-</h3>
-{% if comment_form.comment_field.errors %}
-<div class="alert alert-danger">
-  <strong>
-    <span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
-    Erreur:
-  </strong>
-  Votre commentaire est vide.
-</div>
-{% endif %}
-<table class="table table-striped">
-  <theader>
-    <tr class="info">
-      <th class="col-md-2"> {{comments["author"]}} </td>
-      <th class="col-md-2"> {{comments["opening_date"]}} </td>
-      <th class="col-md-8"> <strong>Titre: {{comments["title"]}}</strong> </td>
-    </tr>
-      <tr>
-        <td colspan="2"/>
-        <td>{{comments["opening_post"]}}</td>
+<div class="container">
+  {% block additional_content %}
+  {% endblock additional_content %}
+  <h3><strong>Discussion</strong></h3></h3>
+  {% if comment_form.comment_field.errors %}
+  <div class="alert alert-danger">
+    <strong>
+      <span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
+      Erreur:
+    </strong>
+    Votre commentaire est vide.
+  </div>
+  {% endif %}
+  <table class="table table-striped">
+    <theader>
+      <tr class="info">
+        <th class="col-md-2"> {{comments["author"]}} </td>
+        <th class="col-md-2"> {{comments["opening_date"]}} </td>
+        <th class="col-md-8"> <strong>Titre: {{comments["title"]}}</strong> </td>
       </tr>
-  </theader>
-  <tbody>
-    {% if comments["comment_list"]|length == 0 %}
-      <tr>
-        <td colspan="3"> Aucun commentaire à afficher </td>
-      </tr>
-    {% else %}
-      {% for comment in comments["comment_list"] %}
+        <tr>
+          <td colspan="2"/>
+          <td>{{comments["opening_post"]}}</td>
+        </tr>
+    </theader>
+    <tbody>
+      {% if comments["comment_list"]|length == 0 %}
         <tr>
-          <td class="col-md-2"> {{comment["author"]}} </td>
-          <td class="col-md-2"> {{comment["date"]}} </td>
-          <td class="col-md-8"> {{comment["body"]}} </td>
+          <td colspan="3"> Aucun commentaire à afficher </td>
         </tr>
-      {% endfor %}
-    {% endif %}
-    <tr class="info tr-pagination">
-      <td colspan="3" class="text-right">
-        {% import "macros.html" as macros %}
-        {{ macros.render_pagination(pagination) }}
-      </td>
-    </tr>
-    <tr class="active">
-      <td colspan="2" class="text-right">
-        {{ comment_form.comment_field.label }}
-      </td>
-      <td>
-        <form method="POST" action="{% block comment_posting_target %}{% endblock %}">
-          <fieldset {% if readonly %}disabled{% endif %}>
-            {{ comment_form.hidden_tag() }}
-            <div class="form-group">
-              {{ comment_form.comment_field(class="form-control", readonly=readonly) }}
-            </div>
-            <button type="submit" class="btn btn-default">Envoyer commentaire</button>
-            <a href="{{ url_for('social.index', repository=current_repository)}}"class="btn btn-default">Retour</a>
-          </fieldset>
-        </form>
-      </td>
-    </tr>
-  </tbody>
-</table>
+      {% else %}
+        {% for comment in comments["comment_list"] %}
+          <tr>
+            <td class="col-md-2"> {{comment["author"]}} </td>
+            <td class="col-md-2"> {{comment["date"]}} </td>
+            <td class="col-md-8"> {{comment["body"]}} </td>
+          </tr>
+        {% endfor %}
+      {% endif %}
+      <tr class="info tr-pagination">
+        <td colspan="3" class="text-right">
+          {% import "macros.html" as macros %}
+          {{ macros.render_pagination(comments_pagination, comments_per_page) }}
+        </td>
+      </tr>
+      <tr class="active">
+        <td colspan="2" class="text-right">
+          {{ comment_form.comment_field.label }}
+        </td>
+        <td>
+          <form method="POST" action="{% block comment_posting_target %}{% endblock %}">
+            <fieldset {% if readonly %}disabled{% endif %}>
+              {{ comment_form.hidden_tag() }}
+              <div class="form-group">
+                {{ comment_form.comment_field(class="form-control", readonly=readonly) }}
+              </div>
+              <button type="submit" class="btn btn-default">Envoyer commentaire</button>
+              <a href="{{ url_for('social.index', repository=current_repository)}}"class="btn btn-default">Retour</a>
+            </fieldset>
+          </form>
+        </td>
+      </tr>
+    </tbody>
+  </table>
+</div>
 {% endblock page_content %}
--- a/src/catedit/templates/social/index.html	Fri Feb 20 10:55:54 2015 +0100
+++ b/src/catedit/templates/social/index.html	Fri Feb 20 18:42:52 2015 +0100
@@ -40,19 +40,33 @@
       </tr>
     </thead>
     <tbody>
-    {% for changeset in changeset_list %}
+    {% if not changeset_list %}
       <tr>
-        <td class="col-md-1">{{changeset["author"]}}</td>
-        <td class="col-md-2">{{changeset["date"]}}</td>
-        <td class="col-md-6">{{changeset["title"]}}</td>
-        <td class="col-md-2">{{changeset["comment_count"]}}</td>
-        <td class="col-md-1">
-          <a href="{{ url_for('social.changeset', repository=current_repository, changeset_id=changeset['id'])}}" title="Voir modifications" class="btn btn-default">
-            <span class=" glyphicon glyphicon-log-in"/>
-          </a>
+        <td colspan="5">
+          Il n'y a aucune modification à afficher.
         </td>
       </tr>
-    {% endfor %}
+    {% else %}
+      {% for changeset in changeset_list %}
+        <tr>
+          <td class="col-md-1">{{changeset["author"]}}</td>
+          <td class="col-md-2">{{changeset["date"]}}</td>
+          <td class="col-md-6">{{changeset["title"]}}</td>
+          <td class="col-md-2">{{changeset["comment_count"]}}</td>
+          <td class="col-md-1">
+            <a href="{{ url_for('social.changeset', repository=current_repository, changeset_id=changeset['id'])}}" title="Voir modifications" class="btn btn-default">
+              <span class=" glyphicon glyphicon-log-in"/>
+            </a>
+          </td>
+        </tr>
+      {% endfor %}
+    {% endif %}
+    <tr>
+      <td class="text-right" colspan = "5">
+        {% import "macros.html" as macros %}
+        {{ macros.render_pagination(commits_pagination, commits_per_page, page_arg_name="commits_page", per_page_arg_name="commits_per_page") }}
+      </td>
+    </tr>
     </tbody>
   </table>
   <h3>Discussions générales</h3>
@@ -74,8 +88,8 @@
     <tbody>
   {% if not discussion_list %}
     <tr>
-      <td colspan="">
-        Il n'y a pas encore de discussion pour cette ensemble de catégories. <a href="#">Créer une discussion</a>
+      <td colspan="5">
+        Il n'y a de discussion à afficher pour cette ensemble de catégories. <a href="#">Créer une discussion</a>
       </td>
     </tr>
   {% else %}
@@ -93,6 +107,11 @@
         </td>
       </tr>
     {% endfor %}
+    <tr>
+      <td class="text-right" colspan = "6">
+        {{ macros.render_pagination(discussions_pagination, discussions_per_page, page_arg_name="discussions_page", per_page_arg_name="discussions_per_page") }}
+      </td>
+    </tr>
   {% endif %}
     </tbody>
   </table>
--- a/src/catedit/views/social.py	Fri Feb 20 10:55:54 2015 +0100
+++ b/src/catedit/views/social.py	Fri Feb 20 18:42:52 2015 +0100
@@ -18,26 +18,91 @@
 logger = app.logger
 
 
-@module.route("/<string:repository>/social",
-              methods=["GET"])
-def index(repository):
+@module.route(
+    "/<string:repository>/social",
+    methods=["GET"],
+    defaults={
+        "commits_page": 1,
+        "commits_per_page": 10,
+        "discussions_page": 1,
+        "discussions_per_page": 10
+    }
+)
+@module.route(
+    "/<string:repository>/social_"
+    + "commits_page<int:commits_page>_perpage<int:commits_per_page>",
+    methods=["GET"],
+    defaults={
+        "discussions_page": 1,
+        "discussions_per_page": 10
+    }
+)
+@module.route(
+    "/<string:repository>/social_"
+    + "discussions_page<int:discussions_page>"
+    + "_perpage<int:discussions_per_page>",
+    methods=["GET"],
+    defaults={
+        "commits_page": 1,
+        "commits_per_page": 10,
+    }
+)
+@module.route(
+    "/<string:repository>/social_"
+    + "commits_page<int:commits_page>_perpage<int:commits_per_page>-"
+    + "discussions_page<int:discussions_page>"
+    + "_perpage<int:discussions_per_page>",
+    methods=["GET"]
+)
+def index(repository, commits_page, commits_per_page,
+          discussions_page, discussions_per_page):
     """
         View that displays every changeset and thread in general discussion
         and links to every thread
     """
-    if repository not in app.config["PERSISTENCE_CONFIG"]["REPOSITORY_LIST"]:
-        abort(404)
-
     check_user_status_and_repo_access(repository)
 
-    changeset_list = get_commits(repository)
-    discussion_list = get_issues(repository)
+    changeset_list = get_commits(
+        repository,
+        commits_per_page,
+        commits_page
+    )
+    if (changeset_list == [] and commits_page != 1
+       and session.get("pagination_links", None) is None):
+        abort(404)
+    commits_pagination = None
+    if session.get("pagination_links", None) is not None:
+        commits_pagination = Pagination(
+            page=session["pagination_links"]["current_page"],
+            per_page=commits_per_page,
+            last_page=session["pagination_links"]["last_page"]
+        )
+        session.pop("pagination_links", None)
+    discussion_list = get_issues(
+        repository,
+        discussions_per_page,
+        discussions_page
+    )
+    if discussion_list == [] and discussions_page != 1:
+        abort(404)
+    discussions_pagination = None
+    if session.get("pagination_links", None) is not None:
+        discussions_pagination = Pagination(
+            page=session["pagination_links"]["current_page"],
+            per_page=discussions_per_page,
+            last_page=session["pagination_links"]["last_page"]
+        )
+        session.pop("pagination_links", None)
 
     return render_template(
         "social/index.html",
         current_repository=repository,
         discussion_list=discussion_list,
-        changeset_list=changeset_list
+        changeset_list=changeset_list,
+        commits_pagination = commits_pagination,
+        commits_per_page = commits_per_page,
+        discussions_pagination = discussions_pagination,
+        discussions_per_page = discussions_per_page
     )
 
 
@@ -73,10 +138,8 @@
         --> Will probably be incorporated into a function later on
 
     """
-    if repository not in app.config["PERSISTENCE_CONFIG"]["REPOSITORY_LIST"]:
-        abort(404)
+    check_user_status_and_repo_access(repository)
 
-    check_user_status_and_repo_access(repository)
     comment_form = CommentForm()
     comments_list = get_comments(
         repository=repository,
@@ -85,6 +148,8 @@
         page=page,
         per_page=per_page
     )
+    if comments_list == [] and page != 1:
+        abort(404)
     pagination=None
     if session.get("pagination_links", None) is not None:
         # If there are multiple pages we create a pagination class that
@@ -94,17 +159,45 @@
             per_page=per_page,
             last_page=session["pagination_links"]["last_page"]
         )
-    cat_list = get_category_list_for_commit(repository, changeset_id)
-
+        session.pop("pagination_links", None)
+    rdf_old_cat_list = get_category_list_for_commit(
+        repository,
+        changeset_id
+    )
+    rdf_new_cat_list = get_category_list_for_commit(
+        repository,
+        changeset_id,
+        get_parent=True
+    )
+    old_cat_list = []
+    for category in rdf_old_cat_list:
+        old_cat_list.append({
+            "cat_label": category.label,
+            "cat_description": category.description,
+            "cat_id": category.cat_id,
+            "cat_properties": category.properties,
+            "state": "original"
+        })
+    new_cat_list = []
+    for category in rdf_new_cat_list:
+        new_cat_list.append({
+            "cat_label": category.label,
+            "cat_description": category.description,
+            "cat_id": category.cat_id,
+            "cat_properties": category.properties,
+            "state": "modified"
+        })
     if request.method == "GET":
         return render_template(
             "social/changeset.html",
-            cat_list=cat_list,
+            old_cat_list=old_cat_list,
+            new_cat_list=new_cat_list,
             comments=comments_list,
             changeset_id=changeset_id,
             comment_form=comment_form,
             current_repository=repository,
-            pagination=pagination
+            comments_pagination=pagination,
+            comments_per_page=per_page
         )
     elif request.method == "POST" and comment_form.validate_on_submit():
         return_id = post_comment(
@@ -128,7 +221,8 @@
             changeset_id=changeset_id,
             comment_form=comment_form,
             current_repository=repository,
-            pagination=pagination
+            comments_pagination=pagination,
+            comments_per_page=per_page
         )
 
 
@@ -161,7 +255,6 @@
         to post comments on it.
     """
     check_user_status_and_repo_access(repository)
-
     comment_form = None
     pagination = None
     if discussion_id == "new":
@@ -176,14 +269,17 @@
             page=page,
             per_page=per_page
         )
+        if comments_list == [] and page != 1:
+            abort(404)
         if session.get("pagination_links", None) is not None:
             # If there are multiple pages we create a pagination class that
             # will be sent to the template
-            pagination = Pagination(
+            comments_pagination = Pagination(
                 page=session["pagination_links"]["current_page"],
                 per_page=per_page,
                 last_page=session["pagination_links"]["last_page"]
             )
+            session.pop("pagination_links", None)
 
     if request.method == "GET":
         return render_template(
@@ -192,7 +288,8 @@
             comment_form=comment_form,
             current_repository=repository,
             discussion_id=discussion_id,
-            pagination=pagination
+            comments_pagination=pagination,
+            comments_per_page=per_page
         )
     elif request.method == "POST" and comment_form.validate_on_submit():
             if discussion_id == "new":
@@ -225,5 +322,6 @@
             comment_form=comment_form,
             current_repository=repository,
             discussion_id=discussion_id,
-            pagination=pagination
+            comments_pagination=pagination,
+            comments_per_page=per_page
         )
--- a/src/catedit/views/utils.py	Fri Feb 20 10:55:54 2015 +0100
+++ b/src/catedit/views/utils.py	Fri Feb 20 18:42:52 2015 +0100
@@ -34,32 +34,20 @@
 
     @property
     def has_next(self):
-        if self.last_page != -1:
-            return self.page < self.pages
-        else:
-            return True
+        return self.page < self.pages
 
     def iter_pages(self, left_edge=2, left_current=2,
                    right_current=5, right_edge=2):
         last = 0
-        if self.last_page != -1:
-            for num in range(1, self.pages+1):
-                if num <= left_edge or \
-                   (num > self.page - left_current - 1 and \
-                    num < self.page + right_current) or \
-                   num > self.pages+1 - right_edge:
-                    if last + 1 != num:
-                        yield None
-                    yield num
-                    last = num
-        else:
-            for num in range(1, self.page+2):
-                if num <= left_edge or \
-                   num > self.page - left_current - 1:
-                    if last + 1 != num:
-                        yield None
-                    yield num
-                    last = num
+        for num in range(1, self.pages+1):
+            if num <= left_edge or \
+               (num > self.page - left_current - 1 and \
+                num < self.page + right_current) or \
+               num > self.pages+1 - right_edge:
+                if last + 1 != num:
+                    yield None
+                yield num
+                last = num
 
 
 def check_user_status_and_repo_access(repository):
@@ -94,15 +82,6 @@
     """
     github_comments_data = []
 
-    if thread_type == "commits":
-        commits_list = get_commits(repository)
-        if thread_id not in [commit["id"] for commit in commits_list]:
-            abort(404)
-    elif thread_type == "issues":
-        issues_list = get_issues(repository)
-        if thread_id not in [issue["id"] for issue in issues_list]:
-            abort(404)
-
     try:
         github_comments_data = github.get(
             "repos/"
@@ -266,8 +245,7 @@
     return return_id
 
 
-@cache.memoize(timeout=3600)
-def get_commits(repository):
+def get_commits(repository, per_page, page):
     """
         Fuction that get the list of commits for a given repository. Returns a
         list of dict with the format:
@@ -284,7 +262,7 @@
             "repos/"
             + app.config["PERSISTENCE_CONFIG"]["REPOSITORY_OWNER"] + "/"
             + repository
-            + "/commits?per_page=5",
+            + "/commits?per_page=" + str(per_page) + "&page=" + str(page),
             hooks=dict(response=save_links)
         )
     except GitHubError as ghe:
@@ -306,8 +284,7 @@
     return changeset_list
 
 
-@cache.memoize(timeout=3600)
-def get_issues(repository):
+def get_issues(repository, per_page=30, page=1):
     """
         Fuction that get the list of issues for a given repository. Returns a
         list of dict with the format:
@@ -326,7 +303,8 @@
             "repos/"
             + app.config["PERSISTENCE_CONFIG"]["REPOSITORY_OWNER"] + "/"
             + repository
-            + "/issues?per_page=100"
+            + "/issues?per_page=" + str(per_page) + "&page=" + str(page),
+            hooks=dict(response=save_links)
         )
     except GitHubError as ghe:
         logger.error("Error getting issues for repo " + repository)
@@ -343,20 +321,14 @@
         }
         for issue in issues_data
     ]
-
-
     return discussion_list
 
 
-@cache.memoize(timeout=3600)
-def get_category_list_for_commit(repository, changeset_id):
+def get_category_list_for_commit(repository, changeset_id, get_parent=False):
     """
         Get the category list as it was following the changeset of
         id changeset_id
     """
-    commits_list = get_commits(repository)
-    if changeset_id not in [commit["id"] for commit in commits_list]:
-        abort(404)
 
     # First step
     commit_data = {}
@@ -371,7 +343,20 @@
         logger.error("Error trying to get the commit of id " + changeset_id)
         logger.error(ghe.response.text)
 
-
+    if get_parent:
+        parents = commit_data.get("parents", [])
+        if parents != []:
+            parent_sha = parents[0].get("sha", "")
+        try:
+            commit_data = github.get(
+                "repos/"
+                + app.config["PERSISTENCE_CONFIG"]["REPOSITORY_OWNER"] + "/"
+                + repository + "/commits/"
+                + parent_sha
+            )
+        except GitHubError as ghe:
+            logger.error("Error trying to get the commit of id " + parent_sha)
+            logger.error(ghe.response.text)
 
     tree_sha = commit_data.get("commit", {}).get("tree", {}).get("sha", "")
 
@@ -389,9 +374,6 @@
         logger.error("Error trying to get the tree of sha " + tree_sha)
         logger.error(ghe.response.text)
 
-
-    logger.debug(tree_data)
-
     # Third step and fourth step
     cat_list = []
     for blob in tree_data.get("tree", []):
@@ -418,16 +400,7 @@
                 format="turtle"
             )
             category = Category(graph=cat_graph)
-            cat_list.append(
-                {
-                    "cat_label": category.label,
-                    "cat_description": category.description,
-                    "cat_id": category.cat_id,
-                    "cat_properties": category.properties,
-                    "state": "original"
-                }
-            )
-
+            cat_list.append(category)
     return cat_list