diff -r b7d19cd87fcf -r 09e00f38d177 src/hdalab/views/profile.py --- a/src/hdalab/views/profile.py Thu Apr 12 01:27:16 2018 +0200 +++ b/src/hdalab/views/profile.py Wed Apr 11 12:19:47 2018 +0200 @@ -5,24 +5,23 @@ @author: tc ''' -from datetime import datetime import json import logging -from renkanmanager.views import RenkanGetPut import uuid +from datetime import datetime from django.conf import settings -from django.contrib.auth import REDIRECT_FIELD_NAME, login as auth_login +from django.contrib.auth import login as auth_login +from django.contrib.auth import REDIRECT_FIELD_NAME from django.contrib.auth.forms import AuthenticationForm from django.contrib.sites.models import get_current_site -from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage +from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator from django.core.urlresolvers import reverse from django.db.models import Q -from django.http import HttpResponse, HttpResponseBadRequest -from django.http import HttpResponseRedirect +from django.http import (HttpResponse, HttpResponseBadRequest, + HttpResponseRedirect) from django.http.response import Http404 -from django.shortcuts import get_object_or_404, redirect -from django.shortcuts import resolve_url +from django.shortcuts import get_object_or_404, redirect, resolve_url from django.template.response import TemplateResponse from django.templatetags.static import static from django.utils.http import is_safe_url @@ -32,22 +31,61 @@ from django.views.decorators.debug import sensitive_post_parameters from django.views.generic import TemplateView, View from django.views.generic.edit import UpdateView -from renkanmanager.models import Renkan -from renkanmanager.utils import LineNodePlacer, HorLineNodePlacer, renkan_copier, renkan_deleter, \ - CircleNodePlacer - -from hdabo.models import Tag, Datasheet, TaggedSheet, Folder -from hdalab.forms import HdalabRenkanStateForm, HdalabRenkanFavoriteForm +from hdabo.models import Datasheet, Folder, Tag, TaggedSheet +from hdalab.forms import HdalabRenkanFavoriteForm, HdalabRenkanStateForm from hdalab.models.dataviz import DbpediaFieldsTranslation from hdalab.models.renkan import HdalabRenkan from hdalab.services import change_renkan_state from hdalab.views.ajax import filter_generic - +from renkanmanager.models import Renkan +from renkanmanager.utils import (CircleNodePlacer, HorLineNodePlacer, + LineNodePlacer, renkan_copier, renkan_deleter) +from renkanmanager.views import RenkanGetPut logger = logging.getLogger(__name__) class BaseRenkanList(TemplateView): + """ + Classe de vue permettant la gestion de l'affichage d'une liste de Renkan. + Cette classe fourni une méthode gérant les filtres, le tri et la pagination. + Cette classe de vue n'est pas directement utilisée mais est dérivé par des classe de vue concrêtes. + + Liste des paramêtres GET: + + +-----------+------------------------------------------------------------+--------+--------+ + | nom | description | type | défaut | + +===========+============================================================+========+========+ + | title | Le titre du renkan contient la chaine de caractères. | chaine | vide | + +-----------+------------------------------------------------------------+--------+--------+ + | username | Le nom de l'utilisateur ayant créé le renkan. | chaine | vide | + +-----------+------------------------------------------------------------+--------+--------+ + | state | Le status du renkan est (c.f. _models/renkan/HdalabRenkan) | entier | (*) | + +-----------+------------------------------------------------------------+--------+--------+ + | startdate | La date de modification du renkan est supérieure à. | epoch | vide | + +-----------+------------------------------------------------------------+--------+--------+ + | enddate | La date de modification du renkan est inférieure à. | epoch | vide | + +-----------+------------------------------------------------------------+--------+--------+ + | favorite | Le renkan est marqué comme favori ou non (0 ou 1) | 0/1 | (*) | + +-----------+------------------------------------------------------------+--------+--------+ + | sort | Champ sur lequel se fait le tri: | chaine | date | + | | - date : date de modification du renkan | /énum. | | + | | - title : titre du renkan | | | + | | - state : status du renkan (c.f _) | | | + | | - user : créateur du renkan | | | + | | - favorite : renkan marqué comme avori | | | + +-----------+------------------------------------------------------------+--------+--------+ + | order | ordre de tri : | chaine | desc | + | | - desc : tri descendant | /énum. | | + | | - asc : tris ascendant | | | + +-----------+------------------------------------------------------------+--------+--------+ + | page | Le numéro de page pour la pagination | entier | 1 | + | | La première page est la page 1. | | | + +-----------+------------------------------------------------------------+--------+--------+ + + (*) : La valeur par défaut de ce paramètre dépend de la vue concrète. + + """ default_sort_field = "date" default_sort_order = "desc" @@ -115,6 +153,11 @@ class ProfileHome(BaseRenkanList): + """ + Page de profile d'un utilisateur. + + Cette vue étend la vue de base :class:`.BaseRenkanList`. + """ template_name = "profile_home.html" @@ -123,6 +166,14 @@ class RenkanPublicList(BaseRenkanList): + """ + Page des renkan publics. + + La colonne de l'auteur du renkan n'est affiché que si l'utilisateur est membre de l'équipe. + Cette list ne comprend pas les renkan marqués commme favoris. Le paramêtre "favorite" est ignoré. + + Cette vue étend la vue de base :class:`.BaseRenkanList`. + """ template_name = "renkan_list.html" @@ -142,6 +193,13 @@ class RenkanFavoriteList(BaseRenkanList): + """ + Page des renkan favoris. Affiche uniquement les renkan marqués comme favoris. Cela implique que le paramêtre "favorite" est ignoré par cette vue. + + La colonne de l'auteur du renkan n'est affiché que si l'utilisateur est membre de l'équipe. + + Cette vue étend la vue de base :class:`.BaseRenkanList`. + """ template_name = "renkan_list_favorite.html" @@ -160,6 +218,10 @@ class RenkanNew(TemplateView): + """ + Page permettant la création de nouveau Renkan vide. + Une fois le renkan est créé (POST), l'utilisateur est redirigé vers la page d'édition de Renkan + """ template_name="renkan_new_confirm.html" @@ -180,6 +242,23 @@ class RenkanEdit(TemplateView): + """ + Page permettant l'édition de Renkan. + Le principal rôle de cette page est d'afficher l'éditeur de Renkan. + + Paramêtres GET pris en compte par cette page: + + +-----------+------------------------------------------------------------+--------+--------+ + | nom | description | type | défaut | + +===========+============================================================+========+========+ + | rk_id | Identifiant d'un renan à éditer. | chaine | vide | + +-----------+------------------------------------------------------------+--------+--------+ + | shape | Forme du renkan généré | chaine | circle | + | | Ce paramêmtre n'a pas d'effet si le renkan existe déjà | | | + | | (utilisation de rk_id) ou bien si il a été sauvegardé. | | | + +-----------+------------------------------------------------------------+--------+--------+ + + """ template_name="renkan_edit.html" @@ -219,12 +298,59 @@ class HdalabRenkanGetPut(RenkanGetPut): + """ + Vue permettant la gestion de la création, de l'édition et de la sauvegarde d'un renkan. + """ @csrf_exempt def dispatch(self, *args, **kwargs): return super(HdalabRenkanGetPut, self).dispatch(*args, **kwargs) def get(self, request): + """ + Méthode qui fournit un renkan au client d'édition. Son origine est fonction des paramêtres fournit. + + Si le paramêtre `rk_id` est fourni, la source du renkan est le contenu d'un objet existant. + Sinon, le renkan est créé à partir des paramêtres fournis. + + Liste des paramêtres de requête: + + +-------------+------------------------------------------------------------+--------+--------+ + | nom | description | type | défaut | + +=============+============================================================+========+========+ + | rk_id | Identifiant d'un renan à éditer. | chaine | vide | + +-------------+------------------------------------------------------------+--------+--------+ + | shape | Forme du renkan généré (circle, vert, hor) | chaine | circle | + | | Ce paramêmtre n'a pas d'effet si le renkan existe déjà | | | + | | (utilisation de rk_id) ou bien si il a été sauvegardé. | | | + +-------------+------------------------------------------------------------+--------+--------+ + | lang | La langue de l'utilisateur. par défaut c'est la langue de | chaine | vide | + | | la requête. | | | + +-------------+------------------------------------------------------------+--------+--------+ + | notice | Un identifiant de notice HDA. Si ce paramêtre est fourni, | chaine | vide | + | | le renkan est généré à partir des tags et notices liées. | | | + | | Le centre du renkan est la notice fournie. | | | + +-------------+------------------------------------------------------------+--------+--------+ + | folder | Identifiant d'un dossier de ressource HDA. Si ce paramêtre | chaine | vide | + | | est fourni, le renkan est généré à partir des notices | | | + | | contenues dans le dossier, ainsi que les tags liés. | | | + +-------------+------------------------------------------------------------+--------+--------+ + | label (*) | Une liste de labels de mots clef, séparés par `,` | chaine | vide | + +-------------+------------------------------------------------------------+--------+--------+ + | country (*) | Une liste d'identifiants de pays, séparés par `,`. Un | chaine | vide | + | | identifiant de pays est sont URI DBPedia. | | | + +-------------+------------------------------------------------------------+--------+--------+ + | period (*) | Période de recherche. | chaine | vide | + | | Le format est `,`. | | | + +-------------+------------------------------------------------------------+--------+--------+ + + + (*) Si les paramêtres `label`, `country`, 'period` sont fournis, ils sont utilisés pour former un filtre sur les fiches HDA en appelant la méthode :func:`hdalab.views.ajax.filter_generic`. + Le résultat de cet appel est ensuite utilisé avec le paramêtre `shape` pour retourner un nouveau renkan. + + Attention, il faut noter que les nouveau projets renkan créés par cette méthode ne sont pas sauvagardé en base et que donc elle n'a pas d'effet de bord. + + """ # If a renkan id is set rk_id = request.GET.get("rk_id", "") @@ -634,6 +760,24 @@ def post(self, request): + """ + Sauvegarde d'un renkan. + La sauvegarde n'est possible que dans les condition suivantes: + - si il s'agit d'une création de renkan (pas de paramêtre `rk_id`), il faut être identifié + - si un renkan est modifié, il faut être identifié et en être le propriétaire. + + Paramêtres de requête: + + +-----------+------------------------------------------------------------+--------+--------+ + | nom | description | type | défaut | + +===========+============================================================+========+========+ + | rk_id | Identifiant du renkan à sauvegarder | chaine | vide | + +-----------+------------------------------------------------------------+--------+--------+ + + Le contenu du renkan à sauvegarder est dans le corps de la requête. + Le contenu d'un renkan est décrit sommairement dans la documentation renkan. + À part pour les champs "id" et "title" qui sont utilisés pour la gestion de l'affichage, le contenu d'un renkan n'est pas modifié par cette meethode et est directement sauvegardé. + """ rk_id = request.GET.get("rk_id", "") #data = json.loads(request.body) @@ -676,8 +820,17 @@ class HdalabRenkanCopy(View): + """ + Vue permettant de copier un renkan. + """ def post(self, request, rk_id): + """ + Copie un renkan. + L'id du renkan à copier est un paramêtre d'URL. + Le nouveau titre est "ancien titre (copy)". + """ + rk = renkan_copier(request.user, rk_id) hr = HdalabRenkan() hr.renkan = rk @@ -689,8 +842,15 @@ class HdalabRenkanDelete(View): + """ + Vue permettant d'effacer un Renkan. + """ def post(self, request, rk_id): + """ + Efface un renkan. + L'id du renkan à copier est un paramêtre d'URL. + """ try: hr = HdalabRenkan.objects.get(renkan__rk_id=rk_id) except: @@ -703,8 +863,35 @@ class HdalabRenkanModerate(View): + """ + Vue pour modérer un renkan. + """ def post(self, request, rk_id): + """ + Modère un Renkan, i.e. modifie son état. + + :param:rk_id: L'identifiant de renkan, passé comme paramêtre d'URL. + + Paramêtres POST: + + +-----------+------------------------------------------------------------+--------+--------+-------------+ + | nom | description | type | défaut | obligatoire | + +===========+============================================================+========+========+=============+ + | id | Identifiant de renkan (n'est pas pris en compte) | chaine | | oui | + +-----------+------------------------------------------------------------+--------+--------+-------------+ + | state | Le prochain état. | entier | | oui | + | | c.f. | | | | + | | :class:`hdalab.models.renkan.HdalabRenkanStateTransition` | | | | + +-----------+------------------------------------------------------------+--------+--------+-------------+ + | message | Message optionel de modération. | chaine | vide | non | + +-----------+------------------------------------------------------------+--------+--------+-------------+ + | next (*) | Url de redirection. | chaine | vide | non | + +-----------+------------------------------------------------------------+--------+--------+-------------+ + + (*) Si non précisée, redirige vers l'url intitulée `profile_home` (/hdalab/profile/). + + """ form = HdalabRenkanStateForm(request.POST) if form.is_valid(): logger.debug("FORM DATA %r", form.cleaned_data) @@ -719,9 +906,28 @@ logger.debug("FORM INVALID %r : %r", request.POST, form.errors) return HttpResponseBadRequest("State form invalid") + + class HdalabRenkanFavorite(View): + """ + Vue pour marquer un renkan comme favori. + """ def post(self, request, rk_id): + """ + Marque un renkan comme favoris. + + :param:rk_id: L'identifiant de renkan, passé comme paramêtre d'URL. + + Paramêtres POST: + + +-----------+------------------------------------------------------------+---------+--------+-------------+ + | nom | description | type | défaut | obligatoire | + +===========+============================================================+=========+========+=============+ + | favorite | Indique si le renkan est marqué comme favoris ou pas | booléen | | oui | + +-----------+------------------------------------------------------------+---------+--------+-------------+ + + """ form = HdalabRenkanFavoriteForm(request.POST) if form.is_valid(): renkan_hda = get_object_or_404(HdalabRenkan.objects.select_related(), renkan__rk_id=rk_id) @@ -734,6 +940,11 @@ class UserProfileUpdate(UpdateView): + """ + Simple classe de vue permettant la gestion des pages de mise à jour des informations de profile de l'utilisateur. + utilise en particulier le template `hdalab/templates/hdabo/user_update_form.html` comme formulaire de saisie. + Elle étend la vue `django.views.generic.edit.UpdateView `_ . + """ fields = ['email'] template_name_suffix = '_update_form' @@ -753,7 +964,8 @@ authentication_form=AuthenticationForm, current_app=None, extra_context=None): """ - Displays the login form and handles the login action. + Affiche le formulaire de connection et gère l'action de connexion. + Cette fonction a été copiée de :func:`django.contrib.auth.views.login` pour faciliter la connexion `ajax`. """ redirect_to = request.REQUEST.get(redirect_field_name, '')