Added cache support for getting issues, commits and comments + reworked workshop page, now displaying latest changes and latest opened issues and links to changeset and issues list + changeset page now displays a change summary
--- a/src/catedit/models.py Fri Feb 20 18:42:52 2015 +0100
+++ b/src/catedit/models.py Mon Mar 02 14:39:22 2015 +0100
@@ -6,6 +6,7 @@
"""
from rdflib import Graph, RDF, RDFS, Literal, URIRef
+from rdflib.compare import to_isomorphic, graph_diff
from uuid import uuid4
from io import StringIO
from slugify import slugify
--- a/src/catedit/static/css/style.css Fri Feb 20 18:42:52 2015 +0100
+++ b/src/catedit/static/css/style.css Mon Mar 02 14:39:22 2015 +0100
@@ -20,10 +20,15 @@
.navbar-form
{
width: 300px;
- vertical-align: center;
+ vertical-align: middle;
display: inline-block;
}
+.cat-changes-item
+{
+ vertical-align: middle;
+}
+
.select-repo
{
float:right;
--- a/src/catedit/static/js/property_functions.js Fri Feb 20 18:42:52 2015 +0100
+++ b/src/catedit/static/js/property_functions.js Mon Mar 02 14:39:22 2015 +0100
@@ -82,7 +82,7 @@
displayCorrespondingField : function() {
propertySelectItem = document.getElementById("property_selector");
- switch(propertySelectItem[propertySelectItem.selectedIndex].label)
+ switch(propertySelectItem[propertySelectItem.selectedIndex].className)
{
case "property_type_default":
document.getElementById("literal-field").className = "hidden form-control";
--- a/src/catedit/templates/categories/editor.html Fri Feb 20 18:42:52 2015 +0100
+++ b/src/catedit/templates/categories/editor.html Mon Mar 02 14:39:22 2015 +0100
@@ -64,7 +64,7 @@
Liste des propriétés ...
</option>
{% for predicate in config["PROPERTY_LIST"] %}
- <option value='{{ predicate }}' label="{{ config['PROPERTY_LIST'][predicate]['descriptive_label_fr'] }}" >{{ config["PROPERTY_LIST"][predicate]["descriptive_label_fr"] }}</option>
+ <option value='{{ predicate }}' label="{{ config['PROPERTY_LIST'][predicate]['descriptive_label_fr'] }}" class="{{ config['PROPERTY_LIST'][predicate]['object_type'] }}">{{ config["PROPERTY_LIST"][predicate]["descriptive_label_fr"] }}</option>
{% endfor %}
</select>
<input type="text" id="literal-field" class="hidden form-control">
--- a/src/catedit/templates/categories/workshop.html Fri Feb 20 18:42:52 2015 +0100
+++ b/src/catedit/templates/categories/workshop.html Mon Mar 02 14:39:22 2015 +0100
@@ -42,7 +42,6 @@
{% endblock repo_list %}
{% block page_content %}
<h2> <b>CatEdit</b> - <small>{{current_repository}}</small></h2>
- <h3> Créer une catégorie : <a href="{{url_for('categories.editor', repository=current_repository)}}" title="Créer catégorie" class="btn btn-default {% if readonly %}disabled{% endif %}"><span class="glyphicon glyphicon-plus"/></a></h3>
{% if session["user_logged"] and not session["user_can_edit"] %}
<div class="alert alert-warning" role="alert">
<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
@@ -83,6 +82,7 @@
</tbody>
</table>
</div>
+ <h4> Créer une catégorie : <a href="{{url_for('categories.editor', repository=current_repository)}}" title="Créer catégorie" class="btn btn-default {% if readonly %}disabled{% endif %}"><span class="glyphicon glyphicon-plus"/></a></h4>
{% if session.get("user_logged") %}
<form method="POST" action="{{url_for('categories.workshop', repository=current_repository)}}" class="form-inline">
<input name="csrf_token" value="{{ csrf_token() }}" type="hidden">
@@ -97,5 +97,77 @@
<h4> Soumettre mes changements actuels : <a href="{{ url_for('categories.submit', repository=current_repository)}}" title="Soumettre changements" class="btn btn-default" {% if readonly %}disabled{% endif %}><span class="glyphicon glyphicon-share"/></a>
</h4>
{% endif %}
- <h3> Discussions sur cet ensemble de catégories : <a href="{{ url_for('social.index', repository=current_repository)}}" title="Aller sur la liste des discussions" class="btn btn-default"><span class="glyphicon glyphicon-comment"/></a></h3>
+ <h3>Modifications récentes</h3>
+ <table class="table table-condensed">
+ <thead>
+ <tr>
+ <th>Auteur</th>
+ <th>Date</th>
+ <th>Message de soumission</th>
+ <th>Commentaires</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% if not changeset_list %}
+ <tr>
+ <td colspan="5">
+ Il n'y a aucune modification à afficher.
+ </td>
+ </tr>
+ {% 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 %}
+ </tbody>
+ </table>
+ <h4>Voir la liste des modifications: <a href="{{ url_for('social.changesets_index', repository=current_repository)}}" title="Voir la liste complète" class="btn btn-default"><span class="glyphicon glyphicon-comment"/></a>
+ </h4>
+ <h3>Discussions récentes</h3>
+ <table class="table table-condensed">
+ <thead>
+ <tr>
+ <th>Auteur</th>
+ <th>Date</th>
+ <th>Titre</th>
+ <th>Commentaires</th>
+ <th>Dernier commentaire</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% if not discussion_list %}
+ <tr>
+ <td colspan="5">
+ Il n'y a de discussion à afficher pour cette ensemble de catégories. <a href="{{ url_for('social.discussion', repository=current_repository, discussion_id='new')}}">Créer une discussion</a>
+ </td>
+ </tr>
+ {% else %}
+ {% for discussion in discussion_list %}
+ <tr>
+ <td class="col-md-1">{{discussion["author"]}}</td>
+ <td class="col-md-2">{{discussion["opening_date"]}}</td>
+ <td class="col-md-5">{{discussion["title"]}}</td>
+ <td class="col-md-1">{{discussion["comment_count"]}}</td>
+ <td class="col-md-2">{{discussion["last_updated"]}}</td>
+ <td class="col-md-1">
+ <a href="{{ url_for('social.discussion', repository=current_repository, discussion_id=discussion['id'])}}" title="Voir la discussion" class="btn btn-default">
+ <span class=" glyphicon glyphicon-log-in"/>
+ </a>
+ </td>
+ </tr>
+ {% endfor %}
+ {% endif %}
+ </tbody>
+ </table>
+ <h4>Voir la liste des discussions: <a href="{{ url_for('social.discussions_index', repository=current_repository)}}" title="Voir la liste complète" class="btn btn-default"><span class="glyphicon glyphicon-comment"/></a>
{% endblock page_content %}
--- a/src/catedit/templates/macros.html Fri Feb 20 18:42:52 2015 +0100
+++ b/src/catedit/templates/macros.html Mon Mar 02 14:39:22 2015 +0100
@@ -1,12 +1,15 @@
-{% macro category_table(cat_list, current_repository, state_list=["mixed"], target="", interactive=True) -%}
+{% macro category_table(cat_list, current_repository, state_list=["mixed"], target="", interactive=True, with_colors=True) -%}
{% for cat in cat_list %}
{% if state_list == ["mixed"] or (cat.state in state_list) %}
- <tr {% if cat.state == "created" %}
- class="success"
- {% elif cat.state == "modified" %}
- class="warning"
- {% elif cat.state == "deleted" %}
- class="danger"
+ <tr
+ {% if with_colors %}
+ {% if cat.state == "created" %}
+ class="success"
+ {% elif cat.state == "modified" %}
+ class="warning"
+ {% elif cat.state == "deleted" %}
+ class="danger"
+ {% endif %}
{% endif %}>
<td class="col-md-2">{{ cat.cat_label }}</td>
<td class="col-md-7">{{ cat.cat_description}}</td>
@@ -48,12 +51,14 @@
{% endif %}
</tr>
<tr
- {% if cat.state == "created" %}
- class="success"
- {% elif cat.state == "modified" %}
- class="warning"
- {% elif cat.state == "deleted" %}
- class="danger"
+ {% if with_colors %}
+ {% if cat.state == "created" %}
+ class="success"
+ {% elif cat.state == "modified" %}
+ class="warning"
+ {% elif cat.state == "deleted" %}
+ class="danger"
+ {% endif %}
{% endif %}>
<td colspan="5">
<div class="cat-info-div" id="properties_{% if (cat.state != 'untouched') and (cat.state != 'original') %}edited_{% endif %}{{cat.cat_id}}">
--- a/src/catedit/templates/social/changeset.html Fri Feb 20 18:42:52 2015 +0100
+++ b/src/catedit/templates/social/changeset.html Mon Mar 02 14:39:22 2015 +0100
@@ -23,13 +23,13 @@
$(".changes-table-toggle").removeClass("btn-info")
$(".changes-box").removeClass("alert-info");
- $(".before-cat-table").slideToggle(function(){
+ $(".before-cat-table").toggle("fast", function(){
$(".before-cat-table-toggle").children().toggleClass("glyphicon-chevron-up glyphicon-chevron-down")
});
- $(".after-cat-table").slideUp(function(){
+ $(".after-cat-table").hide("fast", function(){
$(".after-cat-table-toggle").children().removeClass("glyphicon-chevron-up").addClass("glyphicon-chevron-down");
});
- $(".changes-table").slideUp(function(){
+ $(".changes-table").hide(function(){
$(".changes-table-toggle").children().removeClass("glyphicon-chevron-up").addClass("glyphicon-chevron-down");
});
});
@@ -44,13 +44,13 @@
$(".changes-table-toggle").removeClass("btn-info")
$(".changes-box").removeClass("alert-info");
- $(".after-cat-table").slideToggle(function(){
+ $(".after-cat-table").toggle("fast", function(){
$(".after-cat-table-toggle").children().toggleClass("glyphicon-chevron-up glyphicon-chevron-down")
});
- $(".before-cat-table").slideUp(function(){
+ $(".before-cat-table").hide("fast", function(){
$(".before-cat-table-toggle").children().removeClass("glyphicon-chevron-up").addClass("glyphicon-chevron-down");
});
- $(".changes-table").slideUp(function(){
+ $(".changes-table").hide(function(){
$(".changes-table-toggle").children().removeClass("glyphicon-chevron-up").addClass("glyphicon-chevron-down");
});
});
@@ -68,10 +68,10 @@
$(".changes-table").slideToggle(function(){
$(".changes-table-toggle").children().toggleClass("glyphicon-chevron-up glyphicon-chevron-down")
});
- $(".before-cat-table").slideUp(function(){
+ $(".before-cat-table").hide("fast", function(){
$(".before-cat-table-toggle").children().removeClass("glyphicon-chevron-up").addClass("glyphicon-chevron-down");
});
- $(".after-cat-table").slideUp(function(){
+ $(".after-cat-table").hide("fast", function(){
$(".after-cat-table-toggle").children().removeClass("glyphicon-chevron-up").addClass("glyphicon-chevron-down");
});
});
@@ -155,13 +155,46 @@
</table>
</div>
<div class="changes-table cat-table">
- <table class="table table-striped">
- <tr>
- <td>
- placeholder
- </td>
- </tr>
- </table>
+ <ul class="list-group col-md-12">
+ <li class="list-group-item list-group-item-success">
+ <h4>
+ <b>Catégories ajoutées</b>
+ <span class="badge">{{differences["additions"]|length}}</span>
+ </h4>
+ </li>
+ {% for added_category in differences["additions"] %}
+ <li class="list-group-item">
+ {{ added_category }}
+ </li>
+ {% endfor %}
+ <li class="list-group-item list-group-item-warning">
+ <h4>
+ <b>Catégories modifiées</b>
+ <span class="badge">{{differences["modifications"]|length}}</span>
+ </h4>
+ </li>
+ {% for modified_category in differences["modifications"] %}
+ <li class="list-group-item">
+ {{ modified_category[0] }}
+ <span class="glyphicon glyphicon-chevron-right"></span>
+ {{ modified_category[1] }}
+ <a class="btn btn-default" href="#">
+ <span class="glyphicon glyphicon-log-in"></span>
+ </a>
+ </li>
+ {% endfor %}
+ <li class="list-group-item list-group-item-danger">
+ <h4>
+ <b>Catégories supprimées</b>
+ <span class="badge">{{differences["deletions"]|length}}</span>
+ </h4>
+ </li>
+ {% for deleted_category in differences["deletions"] %}
+ <li class="list-group-item">
+ {{ deleted_category }}
+ </li>
+ {% endfor %}
+</ul>
</div>
<div class="after-cat-table cat-table">
<table class="table table-condensed table-bordered">
@@ -187,13 +220,14 @@
</tr>
{% else %}
{% import "macros.html" as macros %}
- {{ macros.category_table(new_cat_list, current_repository, state_list=["modified"], interactive=False) }}
+ {{ macros.category_table(new_cat_list, current_repository, state_list=["modified"], interactive=False, with_colors=False) }}
{% endif %}
{% endif %}
</tbody>
</table>
</div>
{% endblock additional_content %}
+{% block back_link %}{{ url_for('social.changesets_index', repository=current_repository)}}{% endblock back_link %}
{% block comment_posting_target %}{{url_for("social.changeset", changeset_id=changeset_id, repository=current_repository)}}{% endblock %}
{% block page_content %}
{{super()}}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/catedit/templates/social/changesets_index.html Mon Mar 02 14:39:22 2015 +0100
@@ -0,0 +1,72 @@
+{% extends "layout.html" %}
+{% if not session["user_logged"] or not session["user_can_edit"][current_repository] %}
+ {% set readonly="readonly" %}
+{% else %}
+ {% set readonly=False %}
+{% endif %}
+{% block title %} {{ current_repository}}: Espaces de discussion {% endblock title %}
+{% block head %}
+ {{ super() }}
+{% endblock head %}
+{% block navbar_items %}
+ {{ super() }}
+ {% if session.get("user_logged", None) %}
+ <li><a class="navbar-decorative">></a></li>
+ <li><a href="{{ url_for('categories.workshop', repository=current_repository) }}">Atelier</a></li>
+ <li><a class="navbar-decorative">></a></li>
+ <li class="active"><a>Social</a></li>
+ {% endif %}
+{% endblock navbar_items %}
+{% block repo_list %}
+ {{ super() }}
+{% endblock repo_list %}
+{% block page_content %}
+ <h2> <b>CatEdit</b> - <small>{{current_repository}}</small></h2>
+ {% if readonly %}
+ <div class="alert alert-warning" role="alert">
+ <span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
+ <span class="sr-only">Attention:</span>
+ Vous n'avez pas accès en écriture au repository contenant les catégories - Vous ne pourrez pas poster de commentaires
+ </div>
+ {% endif %}
+ <h3>Historique des modifications</h3>
+ <table class="table table-condensed">
+ <thead>
+ <tr>
+ <th>Auteur</th>
+ <th>Date</th>
+ <th>Message de soumission</th>
+ <th>Commentaires</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% if not changeset_list %}
+ <tr>
+ <td colspan="5">
+ Il n'y a aucune modification à afficher.
+ </td>
+ </tr>
+ {% 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>
+{% endblock page_content%}
--- a/src/catedit/templates/social/comment_thread_layout.html Fri Feb 20 18:42:52 2015 +0100
+++ b/src/catedit/templates/social/comment_thread_layout.html Mon Mar 02 14:39:22 2015 +0100
@@ -8,8 +8,6 @@
{% if session.get("user_logged", None) %}
<li><a class="navbar-decorative">></a></li>
<li><a href="{{ url_for('categories.workshop', repository=current_repository) }}">Atelier</a></li>
- <li><a class="navbar-decorative">></a></li>
- <li><a href="{{ url_for('social.index', repository=current_repository) }}">Social</a></li>
{% endif %}
{% endblock navbar_items %}
{% block page_content %}
@@ -17,66 +15,68 @@
<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>
- <tr>
- <td colspan="2"/>
- <td>{{comments["opening_post"]}}</td>
+ <div>
+ <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(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>
+ {% 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="{% block back_url %}{% endblock %}"class="btn btn-default">Retour</a>
+ </fieldset>
+ </form>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
</div>
{% endblock page_content %}
--- a/src/catedit/templates/social/discussion.html Fri Feb 20 18:42:52 2015 +0100
+++ b/src/catedit/templates/social/discussion.html Mon Mar 02 14:39:22 2015 +0100
@@ -19,7 +19,7 @@
<option value="{{url_for('social.discussion', discussion_id=discussion_id, repository=current_repository, per_page=count, page=1)}}" {% if comments["per_page"]==count %}selected="selected"{% endif %}>{{count}}</option>
{% endfor %}
{% endblock comment_thread_options %}
-
+{% block back_link %}{{ url_for('social.discussions_index', repository=current_repository)}}{% endblock back_link %}
{% block page_content %}
{% if discussion_id == "new" %}
<h2><b>CatEdit</b> - <small>{{current_repository}}</small></h2>
@@ -45,7 +45,7 @@
{{ comment_form.comment_field(class="form-control", readonly=readonly) }}
</div>
<button type="submit" class="btn btn-default">Enregistrer</button>
- <a href="{{ url_for('social.index', repository=current_repository)}}"class="btn btn-default">Retour</a>
+ <a href="{{ url_for('social.discussions_index', repository=current_repository)}}"class="btn btn-default">Retour</a>
</fieldset>
</form>
{% else %}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/catedit/templates/social/discussions_index.html Mon Mar 02 14:39:22 2015 +0100
@@ -0,0 +1,79 @@
+{% extends "layout.html" %}
+{% if not session["user_logged"] or not session["user_can_edit"][current_repository] %}
+ {% set readonly="readonly" %}
+{% else %}
+ {% set readonly=False %}
+{% endif %}
+{% block title %} {{ current_repository}}: Espaces de discussion {% endblock title %}
+{% block head %}
+ {{ super() }}
+{% endblock head %}
+{% block navbar_items %}
+ {{ super() }}
+ {% if session.get("user_logged", None) %}
+ <li><a class="navbar-decorative">></a></li>
+ <li><a href="{{ url_for('categories.workshop', repository=current_repository) }}">Atelier</a></li>
+ <li><a class="navbar-decorative">></a></li>
+ <li class="active"><a>Social</a></li>
+ {% endif %}
+{% endblock navbar_items %}
+{% block repo_list %}
+ {{ super() }}
+{% endblock repo_list %}
+{% block page_content %}
+ <h2> <b>CatEdit</b> - <small>{{current_repository}}</small></h2>
+ {% if readonly %}
+ <div class="alert alert-warning" role="alert">
+ <span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
+ <span class="sr-only">Attention:</span>
+ Vous n'avez pas accès en écriture au repository contenant les catégories - Vous ne pourrez pas poster de commentaires
+ </div>
+ {% endif %}
+ <h3>Discussions générales</h3>
+ <h4> Créer une nouvelle discussion :
+ <a href="{{ url_for('social.discussion', repository=current_repository, discussion_id='new')}}" title="Créer discussion" class="btn btn-default">
+ <span class=" glyphicon glyphicon-plus"/>
+ </a>
+ </h4>
+ <table class="table table-condensed">
+ <thead>
+ <tr>
+ <th>Auteur</th>
+ <th>Date</th>
+ <th>Titre</th>
+ <th>Commentaires</th>
+ <th>Dernier commentaire</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% if not discussions_list %}
+ <tr>
+ <td colspan="5">
+ Il n'y a de discussion à afficher pour cette ensemble de catégories. <a href="{{ url_for('social.discussion', repository=current_repository, discussion_id='new')}}">Créer une discussion</a>
+ </td>
+ </tr>
+ {% else %}
+ {% for discussion in discussions_list %}
+ <tr>
+ <td class="col-md-1">{{discussion["author"]}}</td>
+ <td class="col-md-2">{{discussion["opening_date"]}}</td>
+ <td class="col-md-5">{{discussion["title"]}}</td>
+ <td class="col-md-1">{{discussion["comment_count"]}}</td>
+ <td class="col-md-2">{{discussion["last_updated"]}}</td>
+ <td class="col-md-1">
+ <a href="{{ url_for('social.discussion', repository=current_repository, discussion_id=discussion['id'])}}" title="Voir la discussion" class="btn btn-default">
+ <span class=" glyphicon glyphicon-log-in"/>
+ </a>
+ </td>
+ </tr>
+ {% endfor %}
+ <tr>
+ <td class="text-right" colspan = "6">
+ {% import "macros.html" as macros %}
+ {{ 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>
+{% endblock page_content%}
--- a/src/catedit/templates/social/index.html Fri Feb 20 18:42:52 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,118 +0,0 @@
-{% extends "layout.html" %}
-{% if not session["user_logged"] or not session["user_can_edit"][current_repository] %}
- {% set readonly="readonly" %}
-{% else %}
- {% set readonly=False %}
-{% endif %}
-{% block title %} {{ current_repository}}: Espaces de discussion {% endblock title %}
-{% block head %}
- {{ super() }}
-{% endblock head %}
-{% block navbar_items %}
- {{ super() }}
- {% if session.get("user_logged", None) %}
- <li><a class="navbar-decorative">></a></li>
- <li><a href="{{ url_for('categories.workshop', repository=current_repository) }}">Atelier</a></li>
- <li><a class="navbar-decorative">></a></li>
- <li class="active"><a>Social</a></li>
- {% endif %}
-{% endblock navbar_items %}
-{% block repo_list %}
- {{ super() }}
-{% endblock repo_list %}
-{% block page_content %}
- <h2> <b>CatEdit</b> - <small>{{current_repository}}</small></h2>
- {% if readonly %}
- <div class="alert alert-warning" role="alert">
- <span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
- <span class="sr-only">Attention:</span>
- Vous n'avez pas accès en écriture au repository contenant les catégories - Vous ne pourrez pas poster de commentaires
- </div>
- {% endif %}
- <h3>Historique des modifications</h3>
- <table class="table table-condensed">
- <thead>
- <tr>
- <th>Auteur</th>
- <th>Date</th>
- <th>Message de soumission</th>
- <th>Commentaires</th>
- </tr>
- </thead>
- <tbody>
- {% if not changeset_list %}
- <tr>
- <td colspan="5">
- Il n'y a aucune modification à afficher.
- </td>
- </tr>
- {% 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>
- <h4> Créer une nouvelle discussion :
- <a href="{{ url_for('social.discussion', repository=current_repository, discussion_id='new')}}" title="Créer discussion" class="btn btn-default">
- <span class=" glyphicon glyphicon-plus"/>
- </a>
- </h4>
- <table class="table table-condensed">
- <thead>
- <tr>
- <th>Auteur</th>
- <th>Date</th>
- <th>Titre</th>
- <th>Commentaires</th>
- <th>Dernier commentaire</th>
- </tr>
- </thead>
- <tbody>
- {% if not discussion_list %}
- <tr>
- <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 %}
- {% for discussion in discussion_list %}
- <tr>
- <td class="col-md-1">{{discussion["author"]}}</td>
- <td class="col-md-2">{{discussion["opening_date"]}}</td>
- <td class="col-md-5">{{discussion["title"]}}</td>
- <td class="col-md-1">{{discussion["comment_count"]}}</td>
- <td class="col-md-2">{{discussion["last_updated"]}}</td>
- <td class="col-md-1">
- <a href="{{ url_for('social.discussion', repository=current_repository, discussion_id=discussion['id'])}}" title="Voir la discussion" class="btn btn-default">
- <span class=" glyphicon glyphicon-log-in"/>
- </a>
- </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>
-{% endblock page_content%}
--- a/src/catedit/utils.py Fri Feb 20 18:42:52 2015 +0100
+++ b/src/catedit/utils.py Mon Mar 02 14:39:22 2015 +0100
@@ -1,26 +1,134 @@
-from flask.ext.restful import abort
-from models import Category, CategoryManager
-from rdflib.compare import *
-
-'''
- This function will compare two categories from their Graph object
- serializations.
- Exact return values are to be defined, some ideas
- * check if the 2 categories are the same? (same ID, isomorphic)
- * check if the 2 categories are the same but different version?
- (same ID, not isomorphic)
- * check if unique, non empty parameters changed and list them
- (label and description)
- * returns 2 lists of properties: only_in_first, only_in_second
- * more?
-'''
+"""
+ utils.py:
+ Module that lists utility functions used through the app
+"""
+from catedit import app
+from rdflib import RDF, RDFS
+from rdflib.compare import to_isomorphic, graph_diff
-def compare_two_cat(cat_serial_1, cat_serial_2):
- cat1 = Category(cat_serial_1)
- cat2 = Category(cat_serial_2)
- iso_cat1 = cat1.cat_graph.to_isomorphic()
- iso_cat2 = cat2.cat_graph.to_isomorphic()
- if iso_cat1 != iso_cat2:
- in_both_cats, only_in_cat1, only_in_cat2 = graph_diff(cat1, cat2)
- return
+def compare_categories(first_category, second_category, with_details=True):
+ """
+ Compares 2 categories and generate a dict with 3 lists of
+ differences:
+ * "same_category" is a True/False attribute which is True if both
+ categories have the same id
+ * "same_content" is a True/False attribute which is True if both
+ categories are the exact same
+ * "only_in_first" are the properties we can only find
+ in first_category
+ * "only_in_second" are the properties we can only find
+ in second_category
+ * "in_both" are the properties that can be found in both
+ categories. To be considered "in both" a property has to have the same
+ predicate and object in both categories that must have the same id.
+
+ Each "property" is a triple with predicate id (property key defined in
+ config PROPERTY_LIST) and object (either id if we're referencing
+ another category or the link/text in other cases)
+
+ If both categories are the exact same, returns
+ """
+ compare_result = {}
+ first_iso_cat = to_isomorphic(first_category.cat_graph)
+ second_iso_cat = to_isomorphic(second_category.cat_graph)
+
+ compare_result["same_id"] = (
+ first_category.cat_id == second_category.cat_id
+ )
+ compare_result["same_content"] = (
+ first_iso_cat == second_iso_cat
+ )
+
+ if not(compare_result["same_content"]) and with_details:
+ rdf_in_both = []
+ rdf_only_in_first = []
+ rdf_only_in_second = []
+ rdf_in_both, rdf_only_in_first, rdf_only_in_second = graph_diff(
+ first_category.cat_graph,
+ second_category.cat_graph
+ )
+ in_first = []
+ in_both = []
+ in_second = []
+ for (final_list, diff_list) in [
+ (in_both, rdf_in_both),
+ (in_first, rdf_only_in_first),
+ (in_second, rdf_only_in_second)
+ ]:
+ for triple in diff_list.triples((None, None, None)):
+ if triple[1] == RDFS.label:
+ final_list.append(("label", triple[2].toPython()))
+ elif triple[1] == RDF.Description:
+ final_list.append(("description", triple[2].toPython()))
+ else:
+ for predicate in app.config["PROPERTY_LIST"].keys():
+ if triple[1] == \
+ app.config["PROPERTY_LIST"][predicate]["rdflib_class"]:
+ if (app.config["PROPERTY_LIST"]
+ [predicate]
+ ["object_type"] == "uriref-link"
+ or app.config["PROPERTY_LIST"]
+ [predicate]
+ ["object_type"] == "literal"):
+ final_list.append(
+ (
+ predicate,
+ triple[2].toPython()
+ )
+ )
+ else:
+ final_list.append(
+ (
+ predicate,
+ triple[2].toPython().split("#", 1)[1]
+ )
+ )
+ compare_result["only_in_first"] = in_first
+ compare_result["only_in_second"] = in_second
+ compare_result["in_both"] = in_both
+ print(compare_result)
+ return compare_result
+
+
+
+def make_differences_list(first_category_list, second_category_list):
+ """
+ Compares 2 category lists and generates a dict that lists addition,
+ modification and deletions from first_category_list to
+ second_category_list
+
+ * "additions": list of categories that were added
+ * "modifications" : list of couples before/after of categories that
+ were modified
+ * "deletions": list of categories that were deleted
+ """
+ created_categories = []
+ modified_categories = []
+ deleted_categories = []
+
+ for first_list_category in first_category_list:
+ if first_list_category.cat_id not in [second_list_category.cat_id
+ for second_list_category in second_category_list]:
+ deleted_categories.append(first_list_category)
+ else:
+ for second_list_category in second_category_list:
+ if first_list_category.cat_id == second_list_category.cat_id:
+ if not(compare_categories(
+ first_list_category,
+ second_list_category,
+ with_details=False
+ )["same_content"]):
+ modified_categories.append(
+ (first_list_category, second_list_category)
+ )
+
+ for second_list_category in second_category_list:
+ if second_list_category.cat_id not in [first_list_category.cat_id
+ for first_list_category in first_category_list]:
+ created_categories.append(second_list_category)
+ return {
+ "additions": created_categories,
+ "modifications": modified_categories,
+ "deletions": deleted_categories
+ }
--- a/src/catedit/views/categories.py Fri Feb 20 18:42:52 2015 +0100
+++ b/src/catedit/views/categories.py Mon Mar 02 14:39:22 2015 +0100
@@ -3,12 +3,12 @@
The views functions that handle category management and editing
"""
-from catedit import app, cache
+from catedit import app
from catedit.models import Category
from catedit.views.utils import check_user_status_and_repo_access, \
- get_current_category_list
-from flask import render_template, request, redirect, url_for, session, \
- abort, Blueprint
+ get_current_category_list, get_commits, \
+ get_issues
+from flask import render_template, request, redirect, url_for, abort, Blueprint
from flask_wtf import Form
from catedit.resources import CategoryAPI, CategoryChangesAPI
from wtforms import StringField, TextAreaField, FormField, \
@@ -77,9 +77,23 @@
cat_list = get_current_category_list(repository=repository)
# logger.debug(c.properties)
cat_list = sorted(cat_list, key=lambda cat: cat['cat_id'])
- return render_template('categories/workshop.html',
- cat_list=cat_list,
- current_repository=repository)
+ changeset_list = get_commits(
+ repository,
+ 5,
+ 1
+ )[0]
+ discussion_list = get_issues(
+ repository,
+ 5,
+ 1
+ )[0]
+ return render_template(
+ 'categories/workshop.html',
+ cat_list=cat_list,
+ changeset_list=changeset_list,
+ discussion_list=discussion_list,
+ current_repository=repository
+ )
class CommitForm(Form):
--- a/src/catedit/views/home.py Fri Feb 20 18:42:52 2015 +0100
+++ b/src/catedit/views/home.py Mon Mar 02 14:39:22 2015 +0100
@@ -4,14 +4,9 @@
"""
from catedit import app, github, log_api_rate
-from requests import get
-from requests.auth import HTTPBasicAuth
-from flask import render_template, request, redirect, url_for, \
+from flask import render_template, redirect, url_for, \
session, Blueprint
from flask.ext.github import GitHubError
-from flask_wtf import Form
-from wtforms import StringField, PasswordField
-from wtforms.validators import DataRequired
module = Blueprint('home', __name__)
logger = app.logger
--- a/src/catedit/views/social.py Fri Feb 20 18:42:52 2015 +0100
+++ b/src/catedit/views/social.py Mon Mar 02 14:39:22 2015 +0100
@@ -6,8 +6,8 @@
from catedit import app
from catedit.views.utils import check_user_status_and_repo_access, \
get_comments, post_comment, get_commits, \
- get_issues, get_category_list_for_commit, \
- Pagination
+ get_issues, get_category_list_for_commit
+from catedit.utils import make_differences_list
from flask import render_template, request, redirect, url_for, \
abort, Blueprint, session
from flask_wtf import Form
@@ -19,28 +19,7 @@
@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>",
+ "/<string:repository>/changesets",
methods=["GET"],
defaults={
"commits_page": 1,
@@ -48,61 +27,66 @@
}
)
@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>",
+ "/<string:repository>/changesets"
+ + "/page<int:commits_page>_perpage<int:commits_per_page>",
methods=["GET"]
)
-def index(repository, commits_page, commits_per_page,
- discussions_page, discussions_per_page):
+def changesets_index(repository, commits_page, commits_per_page):
"""
- View that displays every changeset and thread in general discussion
- and links to every thread
+ View that displays every changeset and links to every thread
"""
check_user_status_and_repo_access(repository)
- changeset_list = get_commits(
+ changeset_list, commits_pagination = 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(
+
+ session.pop("pagination_links", None)
+
+ return render_template(
+ "social/changesets_index.html",
+ current_repository=repository,
+ changeset_list=changeset_list,
+ commits_pagination=commits_pagination,
+ commits_per_page=commits_per_page,
+ )
+
+@module.route(
+ "/<string:repository>/discussions",
+ methods=["GET"],
+ defaults={
+ "discussions_page": 1,
+ "discussions_per_page": 10,
+ }
+)
+@module.route(
+ "/<string:repository>/discussions"
+ + "/page<int:discussions_page>_perpage<int:discussions_per_page>",
+ methods=["GET"]
+)
+def discussions_index(repository, discussions_page, discussions_per_page):
+ """
+ View that displays thread in general discussion and links to
+ every thread
+ """
+ check_user_status_and_repo_access(repository)
+
+ discussions_list, discussions_pagination = get_issues(
repository,
discussions_per_page,
discussions_page
)
- if discussion_list == [] and discussions_page != 1:
+ if discussions_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",
+ "social/discussions_index.html",
current_repository=repository,
- discussion_list=discussion_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
+ discussions_list=discussions_list,
+ discussions_pagination=discussions_pagination,
+ discussions_per_page=discussions_per_page,
)
@@ -141,7 +125,7 @@
check_user_status_and_repo_access(repository)
comment_form = CommentForm()
- comments_list = get_comments(
+ comments_list, pagination = get_comments(
repository=repository,
thread_type="commits",
thread_id=changeset_id,
@@ -150,37 +134,43 @@
)
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
- # will be sent to the template
- pagination = Pagination(
- page=session["pagination_links"]["current_page"],
- per_page=per_page,
- last_page=session["pagination_links"]["last_page"]
- )
- 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(
+ old_category_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({
+ new_category_list = get_category_list_for_commit(
+ repository,
+ changeset_id
+ )
+
+ category_differences_dict = {
+ list_type: [
+ (first_category.label, second_category.label)
+ for (first_category, second_category) in diff_list
+ ] if list_type == "modifications" else [
+ category.label
+ for category in diff_list
+ ]
+ for list_type, diff_list in make_differences_list(
+ old_category_list,
+ new_category_list,
+ ).items()
+ }
+
+ old_category_list_template = []
+ for category in old_category_list:
+ old_category_list_template.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({
+
+ new_category_list_template = []
+ for category in new_category_list:
+ new_category_list_template.append({
"cat_label": category.label,
"cat_description": category.description,
"cat_id": category.cat_id,
@@ -190,8 +180,9 @@
if request.method == "GET":
return render_template(
"social/changeset.html",
- old_cat_list=old_cat_list,
- new_cat_list=new_cat_list,
+ old_cat_list=old_category_list_template,
+ new_cat_list=new_category_list_template,
+ differences=category_differences_dict,
comments=comments_list,
changeset_id=changeset_id,
comment_form=comment_form,
@@ -216,7 +207,8 @@
# Form didn't validate
return render_template(
"social/changeset.html",
- cat_list=cat_list,
+ old_cat_list=old_category_list_template,
+ new_cat_list=new_category_list_template,
comments=comments_list,
changeset_id=changeset_id,
comment_form=comment_form,
@@ -262,7 +254,7 @@
comments_list = []
else:
comment_form = CommentForm()
- comments_list = get_comments(
+ comments_list, pagination = get_comments(
repository=repository,
thread_type="issues",
thread_id=discussion_id,
@@ -271,15 +263,6 @@
)
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
- 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(
@@ -292,28 +275,28 @@
comments_per_page=per_page
)
elif request.method == "POST" and comment_form.validate_on_submit():
- if discussion_id == "new":
- return_id = post_comment(
- repository=repository,
- thread_type="issues",
- thread_id=discussion_id,
- comment_body=comment_form.comment_field.data,
- thread_title=comment_form.discussion_title.data
- )
- else:
- return_id = post_comment(
- repository=repository,
- thread_type="issues",
- thread_id=discussion_id,
- comment_body=comment_form.comment_field.data
- )
- return redirect(url_for(
- "social.discussion",
+ if discussion_id == "new":
+ return_id = post_comment(
+ repository=repository,
+ thread_type="issues",
+ thread_id=discussion_id,
+ comment_body=comment_form.comment_field.data,
+ thread_title=comment_form.discussion_title.data
+ )
+ else:
+ return_id = post_comment(
repository=repository,
- discussion_id=return_id,
- page=session["pagination_links"]["last_page"],
- per_page=per_page
- ))
+ thread_type="issues",
+ thread_id=discussion_id,
+ comment_body=comment_form.comment_field.data
+ )
+ return redirect(url_for(
+ "social.discussion",
+ repository=repository,
+ discussion_id=return_id,
+ page=session["pagination_links"]["last_page"],
+ per_page=per_page
+ ))
else:
# Form didn't validate
return render_template(
--- a/src/catedit/views/utils.py Fri Feb 20 18:42:52 2015 +0100
+++ b/src/catedit/views/utils.py Mon Mar 02 14:39:22 2015 +0100
@@ -8,7 +8,7 @@
from catedit import app, github, cache, log_api_rate, save_links
from catedit.models import Category
from catedit.resources import CategoryAPI, CategoryChangesAPI
-from flask import redirect, url_for, session, abort
+from flask import redirect, url_for, session
from flask.ext.github import GitHubError
from datetime import datetime
from rdflib import Graph
@@ -80,105 +80,120 @@
"date": date of the comment format dd/mm/yy hh:mm
}
"""
- github_comments_data = []
-
- try:
- github_comments_data = github.get(
- "repos/"
- + app.config["PERSISTENCE_CONFIG"]["REPOSITORY_OWNER"] + "/"
- + repository + "/"
- + thread_type + "/"
- + thread_id
- + "/comments?per_page=" + str(per_page)
- + "&page=" + str(page),
- hooks=dict(response=save_links)
- )
-
- except GitHubError as ghe:
- logger.error(
- "Error trying to get comments with following data:"
- + " - repository : " + repository
- + " - thread_type : " + thread_type
- + " - thread_id : " + thread_id
- + " - page : " + page
- + " - per_page : " + per_page
- )
- logger.error(ghe.response.text)
-
- comment_list = []
- for comment in github_comments_data:
- comment_dict = {
- "author": comment["user"]["login"],
- "body": comment["body"],
- "date": convert_github_date(
- comment["created_at"]
- )
- }
- comment_list.append(comment_dict)
+ cache_key = "get_comments_" \
+ + repository + "_" \
+ + thread_type + "_" \
+ + thread_id + "_" \
+ + str(page) + "_" + str(per_page)
+ if cache.get(cache_key) is None:
+ github_comments_data = []
- discussion_data = {}
- try:
- discussion_data = github.get(
- "repos/"
- + app.config["PERSISTENCE_CONFIG"]["REPOSITORY_OWNER"] + "/"
- + repository + "/"
- + thread_type + "/"
- + thread_id,
- hooks=dict(response=log_api_rate)
- )
- except GitHubError as ghe:
- logger.error(
- "Error trying to get the or issue of id " + thread_id
- )
- logger.error(
- "endpoint: " + "repos/"
- + app.config["PERSISTENCE_CONFIG"]["REPOSITORY_OWNER"] + "/"
- + repository + "/"
- + thread_type + "/"
- + thread_id
- )
- logger.error(ghe.response.text)
-
- thread_author = ""
- thread_opening_date = ""
- thread_title = ""
- thread_opening_post = ""
-
- route_target = ""
-
- if thread_type == "commits":
- thread_author = discussion_data.get("author", {}).get("login", "")
- thread_opening_date = convert_github_date(
- discussion_data.get(
- "commit",
- {}
- ).get(
- "author",
- {}
- ).get("date", "")
- )
- thread_title = discussion_data.get("commit", {}).get("message", "")
- elif thread_type == "issues":
- route_target = "social.discussion"
- thread_author = discussion_data.get("user", {}).get("login", "")
- thread_opening_date = convert_github_date(
- discussion_data.get("created_at", "0001-01-01T00:00:00Z")
- )
- thread_title = discussion_data.get("title", "")
- thread_opening_post = discussion_data.get("body", "")
+ try:
+ github_comments_data = github.get(
+ "repos/"
+ + app.config["PERSISTENCE_CONFIG"]["REPOSITORY_OWNER"] + "/"
+ + repository + "/"
+ + thread_type + "/"
+ + thread_id
+ + "/comments?per_page=" + str(per_page)
+ + "&page=" + str(page),
+ hooks=dict(response=save_links)
+ )
+ except GitHubError as ghe:
+ logger.error(
+ "Error trying to get comments with following data:"
+ + " - repository : " + repository
+ + " - thread_type : " + thread_type
+ + " - thread_id : " + thread_id
+ + " - page : " + page
+ + " - per_page : " + per_page
+ )
+ logger.error(ghe.response.text)
+ pagination = None
+ 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(
+ page=session["pagination_links"]["current_page"],
+ per_page=per_page,
+ last_page=session["pagination_links"]["last_page"]
+ )
+ session.pop("pagination_links", None)
- thread_dict = {
- "author": thread_author,
- "title": thread_title,
- "opening_date": thread_opening_date,
- "comment_list": comment_list,
- "opening_post": thread_opening_post,
- "per_page": per_page
- }
+ comment_list = []
+ for comment in github_comments_data:
+ comment_dict = {
+ "author": comment["user"]["login"],
+ "body": comment["body"],
+ "date": convert_github_date(
+ comment["created_at"]
+ )
+ }
+ comment_list.append(comment_dict)
+
+ discussion_data = {}
+ try:
+ discussion_data = github.get(
+ "repos/"
+ + app.config["PERSISTENCE_CONFIG"]["REPOSITORY_OWNER"] + "/"
+ + repository + "/"
+ + thread_type + "/"
+ + thread_id,
+ hooks=dict(response=log_api_rate)
+ )
+ except GitHubError as ghe:
+ logger.error(
+ "Error trying to get the commit or issue of id " + thread_id
+ )
+ logger.error(
+ "endpoint: " + "repos/"
+ + app.config["PERSISTENCE_CONFIG"]["REPOSITORY_OWNER"] + "/"
+ + repository + "/"
+ + thread_type + "/"
+ + thread_id
+ )
+ logger.error(ghe.response.text)
- return thread_dict
+ thread_author = ""
+ thread_opening_date = ""
+ thread_title = ""
+ thread_opening_post = ""
+ if thread_type == "commits":
+ thread_author = discussion_data.get("author", {}).get("login", "")
+ thread_opening_date = convert_github_date(
+ discussion_data.get(
+ "commit",
+ {}
+ ).get(
+ "author",
+ {}
+ ).get("date", "")
+ )
+ thread_title = discussion_data.get("commit", {}).get("message", "")
+ elif thread_type == "issues":
+ thread_author = discussion_data.get("user", {}).get("login", "")
+ thread_opening_date = convert_github_date(
+ discussion_data.get("created_at", "0001-01-01T00:00:00Z")
+ )
+ thread_title = discussion_data.get("title", "")
+ thread_opening_post = discussion_data.get("body", "")
+
+
+ thread_dict = {
+ "author": thread_author,
+ "title": thread_title,
+ "opening_date": thread_opening_date,
+ "comment_list": comment_list,
+ "opening_post": thread_opening_post,
+ "per_page": per_page
+ }
+
+ cache.set(cache_key, (thread_dict, pagination), timeout=3600)
+ return (thread_dict, pagination)
+ else:
+ return cache.get(cache_key)
def post_comment(repository, thread_type, thread_id,
comment_body, thread_title=""):
@@ -256,33 +271,48 @@
comment_count : commit comments count
}
"""
- commits_data = []
- try:
- commits_data = github.get(
- "repos/"
- + app.config["PERSISTENCE_CONFIG"]["REPOSITORY_OWNER"] + "/"
- + repository
- + "/commits?per_page=" + str(per_page) + "&page=" + str(page),
- hooks=dict(response=save_links)
- )
- except GitHubError as ghe:
- logger.error("Error getting commits for repo " + repository)
- logger.error(ghe.response.text)
- changeset_list = [
- {
- "id": commit["sha"],
- "title": commit["commit"]["message"],
- "date": convert_github_date(
- commit["commit"]["committer"]["date"]
- ),
- "author": commit["commit"]["committer"]["name"],
- "comment_count": commit["commit"]["comment_count"],
- }
- for commit in commits_data
- ]
+ cache_key = "get_commits_" \
+ + repository + "_" \
+ + str(page) + "_" + str(per_page)
+ if cache.get(cache_key) is None:
+ commits_data = []
+ try:
+ commits_data = github.get(
+ "repos/"
+ + app.config["PERSISTENCE_CONFIG"]["REPOSITORY_OWNER"] + "/"
+ + repository
+ + "/commits?per_page=" + str(per_page) + "&page=" + str(page),
+ hooks=dict(response=save_links)
+ )
+ except GitHubError as ghe:
+ logger.error("Error getting commits for repo " + repository)
+ logger.error(ghe.response.text)
- return changeset_list
+ commits_pagination = None
+ if session.get("pagination_links", None) is not None:
+ commits_pagination = Pagination(
+ page=session["pagination_links"]["current_page"],
+ per_page=per_page,
+ last_page=session["pagination_links"]["last_page"]
+ )
+ session.pop("pagination_links", None)
+ changeset_list = [
+ {
+ "id": commit["sha"],
+ "title": commit["commit"]["message"],
+ "date": convert_github_date(
+ commit["commit"]["committer"]["date"]
+ ),
+ "author": commit["commit"]["committer"]["name"],
+ "comment_count": commit["commit"]["comment_count"],
+ }
+ for commit in commits_data
+ ]
+ cache.set(cache_key, (changeset_list, commits_pagination), timeout=3600)
+ return (changeset_list, commits_pagination)
+ else:
+ return cache.get(cache_key)
def get_issues(repository, per_page=30, page=1):
"""
@@ -297,31 +327,47 @@
comment_count: comments count
}
"""
- issues_data = []
- try:
- issues_data = github.get(
- "repos/"
- + app.config["PERSISTENCE_CONFIG"]["REPOSITORY_OWNER"] + "/"
- + repository
- + "/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)
- logger.error(ghe.response.text)
+ cache_key = "get_issues_" \
+ + repository + "_" \
+ + str(page) + "_" + str(per_page)
+ if cache.get(cache_key) is None:
+ issues_data = []
+ try:
+ issues_data = github.get(
+ "repos/"
+ + app.config["PERSISTENCE_CONFIG"]["REPOSITORY_OWNER"] + "/"
+ + repository
+ + "/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)
+ logger.error(ghe.response.text)
- discussion_list = [
- {
- "id": str(issue["number"]),
- "title": issue["title"],
- "author": issue["user"]["login"],
- "opening_date": convert_github_date(issue["created_at"]),
- "last_updated": convert_github_date(issue["updated_at"]),
- "comment_count": issue["comments"],
- }
- for issue in issues_data
- ]
- return discussion_list
+ discussions_pagination = None
+ if session.get("pagination_links", None) is not None:
+ discussions_pagination = Pagination(
+ page=session["pagination_links"]["current_page"],
+ per_page=per_page,
+ last_page=session["pagination_links"]["last_page"]
+ )
+ session.pop("pagination_links", None)
+
+ discussion_list = [
+ {
+ "id": str(issue["number"]),
+ "title": issue["title"],
+ "author": issue["user"]["login"],
+ "opening_date": convert_github_date(issue["created_at"]),
+ "last_updated": convert_github_date(issue["updated_at"]),
+ "comment_count": issue["comments"],
+ }
+ for issue in issues_data
+ ]
+ cache.set(cache_key, (discussion_list, discussions_pagination), timeout=3600)
+ return (discussion_list, discussions_pagination)
+ else:
+ return cache.get(cache_key)
def get_category_list_for_commit(repository, changeset_id, get_parent=False):
@@ -329,79 +375,91 @@
Get the category list as it was following the changeset of
id changeset_id
"""
-
- # First step
- commit_data = {}
- try:
- commit_data = github.get(
- "repos/"
- + app.config["PERSISTENCE_CONFIG"]["REPOSITORY_OWNER"] + "/"
- + repository + "/commits/"
- + changeset_id
- )
- except GitHubError as ghe:
- 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", "")
+ cache_key = "get_category_list_for_commit_" \
+ + repository + "_" \
+ + changeset_id + "_parent_" + str(get_parent)
+ if cache.get(cache_key) is None:
+ # First step
+ commit_data = {}
try:
commit_data = github.get(
"repos/"
+ app.config["PERSISTENCE_CONFIG"]["REPOSITORY_OWNER"] + "/"
+ repository + "/commits/"
- + parent_sha
+ + changeset_id
)
except GitHubError as ghe:
- logger.error("Error trying to get the commit of id " + parent_sha)
+ logger.error(
+ "Error trying to get the commit of id " + changeset_id
+ )
logger.error(ghe.response.text)
- tree_sha = commit_data.get("commit", {}).get("tree", {}).get("sha", "")
-
- # Second step
- tree_data = {}
- try:
- tree_data = github.get(
- "repos/"
- + app.config["PERSISTENCE_CONFIG"]["REPOSITORY_OWNER"] + "/"
- + repository + "/git/trees/"
- + commit_data["commit"]["tree"]["sha"]
- + "?recursive=1"
- )
- except GitHubError as ghe:
- logger.error("Error trying to get the tree of sha " + tree_sha)
- logger.error(ghe.response.text)
-
- # Third step and fourth step
- cat_list = []
- for blob in tree_data.get("tree", []):
- if app.config["PERSISTENCE_CONFIG"]["CATEGORIES_PATH"] in blob["path"]:
- blob_data = {}
+ parent_sha = ""
+ if get_parent:
+ parents = commit_data.get("parents", [])
+ if parents != []:
+ parent_sha = parents[0].get("sha", "")
try:
- blob_data = github.get(
+ commit_data = github.get(
"repos/"
+ app.config["PERSISTENCE_CONFIG"]["REPOSITORY_OWNER"]
- + "/" + repository + "/git/blobs/"
- + blob["sha"]
+ + "/" + repository + "/commits/"
+ + parent_sha
)
except GitHubError as ghe:
logger.error(
- "Error trying to get the blob of sha " + blob["sha"]
+ "Error trying to get the commit of id " + parent_sha
)
logger.error(ghe.response.text)
- cat_graph = Graph()
- cat_graph.parse(
- source=StringIO(
- str(b64decode(blob_data["content"]), "utf-8")
- ),
- format="turtle"
+ tree_sha = commit_data.get("commit", {}).get("tree", {}).get("sha", "")
+
+ # Second step
+ tree_data = {}
+ try:
+ tree_data = github.get(
+ "repos/"
+ + app.config["PERSISTENCE_CONFIG"]["REPOSITORY_OWNER"] + "/"
+ + repository + "/git/trees/"
+ + commit_data["commit"]["tree"]["sha"]
+ + "?recursive=1"
)
- category = Category(graph=cat_graph)
- cat_list.append(category)
- return cat_list
+ except GitHubError as ghe:
+ logger.error("Error trying to get the tree of sha " + tree_sha)
+ logger.error(ghe.response.text)
+
+ # Third step and fourth step
+ cat_list = []
+ for blob in tree_data.get("tree", []):
+ if app.config["PERSISTENCE_CONFIG"]["CATEGORIES_PATH"] \
+ in blob["path"]:
+ blob_data = {}
+ try:
+ blob_data = github.get(
+ "repos/"
+ + app.config["PERSISTENCE_CONFIG"]["REPOSITORY_OWNER"]
+ + "/" + repository + "/git/blobs/"
+ + blob["sha"]
+ )
+ except GitHubError as ghe:
+ logger.error(
+ "Error trying to get the blob of sha " + blob["sha"]
+ )
+ logger.error(ghe.response.text)
+
+ cat_graph = Graph()
+ cat_graph.parse(
+ source=StringIO(
+ str(b64decode(blob_data["content"]), "utf-8")
+ ),
+ format="turtle"
+ )
+ category = Category(graph=cat_graph)
+ cat_list.append(category)
+ cache.set(cache_key, cat_list, timeout=3600)
+ return cat_list
+ else:
+ return cache.get(cache_key)
def convert_github_date(date):
@@ -430,6 +488,9 @@
"state": category state (one of {"untouched", "created",
"edited", "deleted"})
}
+
+ Caching it is unecessary because the API call to get the list is
+ already cached
"""
cat_api_instance = CategoryAPI()
cat_changes_api_instance = CategoryChangesAPI()
@@ -486,10 +547,6 @@
# now we must find the not yet submitted categories that were created
cat_state = ""
- logger.debug("Edited cat list: "
- + str([cat.label for cat in edited_cat_list])
- + " - Original cat list: "
- + str([cat.label for cat in original_cat_list]))
for category in edited_cat_list:
if category.cat_id not in [cat.cat_id for
cat in original_cat_list]: