src/hdalab/views/profile.py
author ymh <ymh.work@gmail.com>
Tue, 10 Mar 2015 18:41:29 +0100
changeset 529 f479d60ca502
parent 490 97afeb38e259
child 531 82758bd0ce10
permissions -rw-r--r--
form to change profile info

# -*- coding: utf-8 -*-
'''
Created on Jul 01, 2014

@author: tc
'''

from datetime import datetime
import json
import logging
from renkanmanager.models import Renkan
from renkanmanager.utils import LineNodePlacer, HorLineNodePlacer, renkan_copier, renkan_deleter, \
    CircleNodePlacer
from renkanmanager.views import RenkanGetPut
import uuid

from django.conf import settings
from django.contrib.auth import REDIRECT_FIELD_NAME, login as auth_login, \
    get_user_model
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.urlresolvers import reverse, reverse_lazy
from django.db.models import Q
from django.http import HttpResponse, HttpResponseBadRequest
from django.http import HttpResponseRedirect
from django.http.response import Http404
from django.shortcuts import get_object_or_404, redirect
from django.shortcuts import resolve_url
from django.template.response import TemplateResponse
from django.templatetags.static import static
from django.utils.http import is_safe_url
from django.utils.translation import ugettext as _
from django.views.decorators.cache import never_cache
from django.views.decorators.csrf import csrf_exempt, csrf_protect
from django.views.decorators.debug import sensitive_post_parameters
from django.views.generic import TemplateView, View
from django.views.generic.edit import UpdateView

from hdabo.models import Tag, Datasheet, TaggedSheet, Folder
from hdalab.forms import HdalabRenkanStateForm, HdalabRenkanFavoriteForm
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


User = get_user_model()

logger = logging.getLogger(__name__)


class BaseRenkanList(TemplateView):
    
    def update_context(self, context, renkan_queryset):
        
        filters = ""
        filter_title = self.request.GET.get("title", "")
        if(len(filter_title)>0):
            renkan_queryset = renkan_queryset.filter(renkan__title__icontains=filter_title)
            filters += "&title=" + filter_title
        filter_username = self.request.GET.get("username", "")
        if(len(filter_username)>0):
            renkan_queryset = renkan_queryset.filter(renkan__owner__username=filter_username)
            filters += "&username=" + filter_username
        filter_state = self.request.GET.get("state", "")
        if(len(filter_state)>0):
            try:
                filter_state = int(filter_state)
            except:
                pass
            renkan_queryset = renkan_queryset.filter(state=filter_state)
            filter_state = str(filter_state)
            filters += "&state=" + filter_state
        filter_startdate = self.request.GET.get("startdate", "")
        if filter_startdate!="":
            renkan_queryset = renkan_queryset.filter(renkan__modification_date__gt=filter_startdate)
            filters += "&startdate=" + filter_startdate
        filter_enddate = self.request.GET.get("enddate", "")
        if filter_enddate!="":
            renkan_queryset = renkan_queryset.filter(renkan__modification_date__lt=filter_enddate + " 23:59:59")
            filters += "&enddate=" + filter_enddate
        filter_favorite = int(self.request.GET.get('favorite', "2"))
        if filter_favorite == 1:
            renkan_queryset = renkan_queryset.filter(favorite=True)
        elif filter_favorite == 0:
            renkan_queryset = renkan_queryset.filter(favorite=False)

        sort_param = self.request.GET.get('sort', "date")
        order_param = self.request.GET.get('order', "desc")
        sort = {"date":"renkan__modification_date", "title":"renkan__title", "state":"state", "user":"renkan__owner__username", "favorite":"favorite"}.get(sort_param, None)
        if order_param=="desc":
            order = "-"
            opposite = "asc"
        else:
            order = ""
            opposite = "desc"
        if sort:
            renkan_queryset = renkan_queryset.order_by(order + sort)
        p = Paginator(renkan_queryset, settings.RENKANS_PER_PAGE)
        page_nb = self.request.GET.get('page')
        try:
            page = p.page(page_nb)
        except PageNotAnInteger:
            page = p.page(1)
        except EmptyPage:
            page = p.page(p.num_pages)
        
        context.update({"page": page, "sort_param":sort_param, "order_param":order_param, "opposite":opposite, 
                        "filters":filters, "title": filter_title, "username": filter_username, "state": filter_state,
                        "startdate":filter_startdate, "enddate":filter_enddate, "favorite": filter_favorite})
        
        return context



class ProfileHome(BaseRenkanList):
    
    template_name = "profile_home.html"
    
    def get_context_data(self, **kwargs):
        return self.update_context( super(ProfileHome, self).get_context_data(**kwargs), HdalabRenkan.objects.select_related("renkan").filter(renkan__owner=self.request.user))


class RenkanPublicList(BaseRenkanList):
    
    template_name = "renkan_list.html"
    
    def get_context_data(self, **kwargs):
        return self.update_context( super(RenkanPublicList, self).get_context_data(**kwargs), HdalabRenkan.objects.select_related("renkan", "renkan__owner").filter(state=HdalabRenkan.PUBLISHED) )


class RenkanFavoriteList(BaseRenkanList):
    
    template_name = "renkan_list.html"
    
    def get_context_data(self, **kwargs):
        context = super(BaseRenkanList, self).get_context_data(**kwargs)
        context['hide_favorite'] = True
        return self.update_context(context , HdalabRenkan.objects.select_related("renkan", "renkan__owner").filter(state=HdalabRenkan.PUBLISHED, favorite=True) )


class RenkanNew(View):
    
    def post(self, request):
        rk = Renkan()
        rk_id = unicode(uuid.uuid1())
        rk.rk_id = rk_id
        rk.owner = request.user
        rk.content = '{}'
        rk.title = "Nouveau Renkan "
        rk.save()
        hr = HdalabRenkan()
        hr.renkan = rk
        hr.state = HdalabRenkan.EDITION
        hr.save()
        return redirect("%s?rk_id=%s" % (reverse('renkan_edit'), rk_id))


class RenkanEdit(TemplateView):
    
    template_name="renkan_edit.html"
    
    def get_context_data(self, **kwargs):
        switch_shape_url= {}
        context = super(RenkanEdit, self).get_context_data(**kwargs)
        # If a renkan id is set
        rk_id = self.request.GET.get("rk_id", "")
        if rk_id!="":
            hr = get_object_or_404(HdalabRenkan.objects.select_related("renkan", "renkan__owner"), renkan__rk_id=rk_id) #.get(=rk_id)
            if hr.renkan.owner!=self.request.user or hr.state!=HdalabRenkan.EDITION:
                raise Exception("You are not allowed to edit this renkan")
        else:
            current_url = self.request.get_full_path()
            switch_shape_url["current"] = current_url
            if "shape=horiz" in current_url:
                switch_shape_url["vert"] = current_url.replace("&shape=horiz", "&shape=vert")
                switch_shape_url["circle"] = current_url.replace("&shape=horiz", "")
            elif "shape=vert" in current_url:
                switch_shape_url["horiz"] = current_url.replace("&shape=vert", "&shape=horiz")
                switch_shape_url["circle"] = current_url.replace("&shape=vert", "")
            else:
                #if we generated the renkan from no filter, the url doesn't have any "?"
                #we add one to create the links to the other representation
                if "?" not in current_url:
                    current_url += "?"
                switch_shape_url["horiz"] = current_url + "&shape=horiz"
                switch_shape_url["vert"] = current_url + "&shape=vert"
            context["switch_shape_url"] = switch_shape_url
        form = AuthenticationForm(self.request)
        context["form"] = form
        
        return context



class HdalabRenkanGetPut(RenkanGetPut):
    
    @csrf_exempt
    def dispatch(self, *args, **kwargs):
        return super(HdalabRenkanGetPut, self).dispatch(*args, **kwargs)
    
    def get(self, request):
        
        # If a renkan id is set
        rk_id = request.GET.get("rk_id", "")
        if rk_id!="":
            rk = get_object_or_404(Renkan, rk_id=rk_id)
            return HttpResponse(rk.content, content_type="application/json")
        
        shape = request.GET.get("shape", "")
        no_translate_langs = [ 'fr' ]
        lang = request.GET.get('lang',request.LANGUAGE_CODE)
        
        # Start dict for renkan json
        now = datetime.now().strftime("%Y-%m-%d %H:%M")
        
        content = {
          "id": unicode(uuid.uuid1()),
          "title": "",
          "description": "(empty description)",
          "created": now,
          "updated": now,
          "nodes": [],
          "edges": [],
          "views": [],
          "users": [],
        }
        
        # category image dict
        cat_dict = {u"Créateur": static("hdalab/img/category_creator.png"),
                    u"Datation": static("hdalab/img/category_datation.png"),
                    u"Discipline artistique": static("hdalab/img/category_discipline.png"),
                    u"Localisation": static("hdalab/img/category_localisation.png"),
                    u"Ecole/Mouvement": static("hdalab/img/category_movement.png")}
        
        # category image dict
        shapes = { "tag1": "polygon", "notice": "rectangle", "tag2": "star" }
        
        
        # Renkan Project ID
        project_id = unicode(uuid.uuid1())
        
        
        # If a notice id is set
        notice_id = request.GET.get("notice", "")
        if notice_id!="":
            notice = get_object_or_404(Datasheet, hda_id=notice_id)
            # We get the ORDERED tags if we display one sheet
            ordered_tags = TaggedSheet.objects.filter(datasheet=notice).select_related("tag", "tag__dbpedia_fields", "tag__category").order_by('order')[:15]
            # Prepare Node placer :
            np = CircleNodePlacer()
            if shape=="horiz":
                np = HorLineNodePlacer()
            elif shape=="vert":
                np = LineNodePlacer()
                
            np.init({"datasheet": (1, 1), "tags": (2, len(ordered_tags))})
            # Place notice :
            content["nodes"].append({
                "id": unicode(uuid.uuid1()),
                "title": notice.title,
                "description": notice.description,
                "uri": notice.url,
                "position": np.get_place("datasheet"),
                "image": "http://www.histoiredesarts.culture.fr/images/pf/" + notice.hda_id + ".jpg",
                "size": 0,
                "project_id": project_id,
                "color": "#FF0033",
                #"created_by": "roster_user-84fe909f-ba37-48e6-a25f-9d2f129a95b7",
                "shape": shapes["notice"]
            })
            notice_id = content["nodes"][0]["id"]
            
            # Get translated labels
            translations = {}
            if lang not in no_translate_langs:
                transqs = DbpediaFieldsTranslation.objects.filter(master__in = [ot.tag.dbpedia_fields if hasattr(ot.tag, 'dbpedia_fields') and ot.tag.dbpedia_fields else None for ot in ordered_tags], language_code = lang)
                translations = dict([(trans.master_id,trans) for trans in transqs])
            
            for ot in ordered_tags:
                t = ot.tag
                img_url = t.dbpedia_fields.thumbnail if hasattr(t, 'dbpedia_fields') and t.dbpedia_fields and t.dbpedia_fields.thumbnail else None
                if img_url is None and t.category is not None:
                    img_url = cat_dict[t.category.label]
                translation_obj = translations.get(t.dbpedia_fields.id, None) if t.dbpedia_fields else None
                translation = {
                    'label': translation_obj.label if translation_obj and translation_obj.label else t.label,
                    'abstract': translation_obj.abstract if translation_obj and translation_obj.abstract else '',
                }
                content["nodes"].append({
                  "id": unicode(uuid.uuid1()),
                  "title": translation['label'],
                  "description": translation['abstract'],
                  "uri": t.wikipedia_url,
                  "position": np.get_place("tags"),
                  "image": img_url,
                  "size": 0,
                  "project_id": project_id,
                  "color": "#00FF33",
                  #"created_by": "roster_user-84fe909f-ba37-48e6-a25f-9d2f129a95b7",
                  "shape": shapes["tag2"]
                })
                
            # Place edges
            for node in content["nodes"]:
                content["edges"].append({
                    "id": unicode(uuid.uuid1()),
                    "title": "",
                    "description": "",
                    "uri": "",
                    "color": None,
                    "from": notice_id,
                    "to": node["id"],
                    "project_id": project_id,
                    #"created_by": "de68xf75y6hs5rgjhgghxbm217xk"
                })
            
            response = json.dumps(content)
            return HttpResponse(response, content_type="application/json")
        
        
        # If a folder id is set
        folder_id = request.GET.get("folder", "")
        if folder_id!="":
            #TODO : optimize to avoid tag request on each notice
            folder = get_object_or_404(Folder.objects.select_related("datasheets", "datasheets__tags"), pk=folder_id)
            notices = folder.datasheets.all()
            n_tags = []
            notice_tag_dict = {}
            tag_uuid_dict = {}
            for n in notices:
                notice_tag_dict[n.pk] = {"uuid":unicode(uuid.uuid1()), "tags":[] }
                for t in n.tags.all()[:5]:
                    if t.pk not in tag_uuid_dict:
                        tag_uuid_dict[t.pk] = unicode(uuid.uuid1())
                    notice_tag_dict[n.pk]["tags"].append(tag_uuid_dict[t.pk])
                    n_tags.append(t)
            n_tags = [t.pk for t in n_tags]
            all_tags = Tag.objects.filter( pk__in=n_tags ).select_related("dbpedia_fields", "category")
            
            # Get translated labels
            translations = {}
            if lang not in no_translate_langs:
                transqs = DbpediaFieldsTranslation.objects.filter(master__in = [t.dbpedia_fields if hasattr(t, 'dbpedia_fields') and t.dbpedia_fields else None for t in all_tags], language_code = lang)
                translations = dict([(trans.master_id,trans) for trans in transqs])
            
            # Prepare Node placer :
            np = CircleNodePlacer()
            if shape=="horiz":
                np = HorLineNodePlacer()
            elif shape=="vert":
                np = LineNodePlacer()
                
            np.init({"datasheet": (1, len(notices)), "tags": (2, len(all_tags))})

            
            # Place notices
            for n in notices:
                content["nodes"].append({
                  "id": notice_tag_dict[n.pk]["uuid"],
                  "title": n.title,
                  "description": n.description,
                  "uri": n.url,
                  "position": np.get_place("datasheet"),
                  "image": "http://www.histoiredesarts.culture.fr/images/pf/" + n.hda_id + ".jpg",
                  "size": 0,
                  "project_id": project_id,
                  "color": "#FF0033",
                  #"created_by": "roster_user-84fe909f-ba37-48e6-a25f-9d2f129a95b7",
                  "shape": shapes["notice"]
                })
            
            # Place tags
            for t in all_tags:
                img_url = t.dbpedia_fields.thumbnail if hasattr(t, 'dbpedia_fields') and t.dbpedia_fields and t.dbpedia_fields.thumbnail else None
                translation_obj = translations.get(t.dbpedia_fields.id, None) if t.dbpedia_fields else None
                translation = {
                    'label': translation_obj.label if translation_obj and translation_obj.label else t.label,
                    'abstract': translation_obj.abstract if translation_obj and translation_obj.abstract else '',
                }

                if img_url is None and t.category is not None:
                    img_url = cat_dict[t.category.label]
                content["nodes"].append({
                  "id": tag_uuid_dict[t.pk],
                  "title": translation['label'],
                  "description": translation['abstract'],
                  "uri": t.wikipedia_url,
                  "position": np.get_place("tags"),
                  "image": img_url,
                  "size": 0,
                  "project_id": project_id,
                  "color": "#00FF33",
                  #"created_by": "roster_user-84fe909f-ba37-48e6-a25f-9d2f129a95b7",
                  "shape": shapes["tag2"]
                })
            
            # Place edges
            for n_pk in notice_tag_dict:
                for tag_id in notice_tag_dict[n_pk]["tags"]:
                    content["edges"].append({
                        "id": unicode(uuid.uuid1()),
                        "title": "",
                        "description": "",
                        "uri": "",
                        "color": None,
                        "from": notice_tag_dict[n_pk]["uuid"],
                        "to": tag_id,
                        "project_id": project_id,
                        #"created_by": "de68xf75y6hs5rgjhgghxbm217xk"
                    })
            
            response = json.dumps(content)
            return HttpResponse(response, content_type="application/json")
            
        
        # Otherwise we build the datas
        # Get tags and countries
        labels = request.GET.get("label", "").split(",")
        countries = request.GET.get("country", "").split(",")
        period = request.GET.get("period", None)
        # Tags arrive with french label, countries with dbpedia uri
        label_list = [t for t in labels if t!=""]
        country_list = [c for c in countries if c!=""]
        all_tags = Tag.objects.filter( Q(label__in=label_list) | Q(dbpedia_uri__in=country_list) ).select_related("dbpedia_fields", "category")
        
        # Get datasheets from ajax filter search
        temp_fitler = filter_generic(lang, period, ",".join(label_list), ",".join(country_list), content_count=18)
        filter_output = json.loads(temp_fitler)
        filter_output_to_bin = json.loads(temp_fitler)
        
        #Keep only the 8 first ressources to create the graph
        #the 10 next are sent to the bins
        for i in range(len(filter_output["contents"])):
            if (i < 8):
                del filter_output_to_bin["contents"][0]
            else:
                del filter_output["contents"][8]

        content["bins"] = {
          "type": "ResourceList",
          "title": _("Plus de Ressources"), #TODO: Translate
          "list": filter_output_to_bin["contents"]
        }
        
        # Prepare other tags
        related_tags = []
        all_labels = [t.label for t in all_tags]
        title = "Recherche " + ", ".join(all_labels)
        if period:
            title += ", " + _("Period") + " " + period
        content["title"] = title
        related_tags_dict = {}
        for c in filter_output["contents"]:
            c["id"] = unicode(uuid.uuid1())
            related_tags_dict[c["id"]] = []
            for t in c["tags"]:
                if t["label"] not in all_labels and t["order"]<6:
                    thumbnail_url = ""
                    for tt in filter_output["tags"]:
                        if tt["label"]==t["label"]:
                            thumbnail_url = tt["thumbnail"]
                    related_tags.append({"label": t["label"], "thumbnail":thumbnail_url, "id":t["id"], "url":t["url"], 'wkpd_url': t['wkpd_url']})
                    all_labels.append(t["label"])
                related_tags_dict[c["id"]].append(t["id"])
        
        
        # If possible, we search a dbpedia_fields thumbnail or category thumbnail for related tags
        r_tags = [t["label"] for t in related_tags if t["thumbnail"] is None or t["thumbnail"]=="" ]
        r_tags = Tag.objects.filter( label__in=r_tags ).select_related("dbpedia_fields", "category")
        r_tags_dict = {}
        for t in r_tags:
            img_url = t.dbpedia_fields.thumbnail if hasattr(t, 'dbpedia_fields') and t.dbpedia_fields and t.dbpedia_fields.thumbnail else None
            if img_url is None and t.category is not None:
                img_url = cat_dict[t.category.label]
            if img_url:
                r_tags_dict[t.label] = img_url
        # Populate related_tags with found image urls
        for t in related_tags:
            if (t["thumbnail"] is None or t["thumbnail"]=="") and (t["label"] in r_tags_dict):
                t["thumbnail"] = r_tags_dict[t["label"]]
        
        
        # Prepare Node placer :
        np = CircleNodePlacer()
        if shape=="horiz":
            np = HorLineNodePlacer()
        elif shape=="vert":
            np = LineNodePlacer()
            
        len_tags = len(all_tags)
        if period:
            len_tags += 1
        np.init({"tags": (1, len_tags), "datasheet": (2, len(filter_output["contents"])), "related": (3, len(related_tags)), "northwest":(3 if shape=="circle" else 1, 1)})
        
        #get tag abstract and label translations
        
        tags_id = [t.id for t in all_tags] + [t['id'] for t in related_tags]
        translations = {}
        transqs = DbpediaFieldsTranslation.objects.filter(master__tag__in = tags_id, language_code = lang)
        translations = dict([(trans.master.tag.id,trans) for trans in transqs])

        
        for t in all_tags:
            img_url = t.dbpedia_fields.thumbnail if hasattr(t, 'dbpedia_fields') and t.dbpedia_fields and t.dbpedia_fields.thumbnail else None
            if img_url is None and t.category is not None:
                img_url = cat_dict[t.category.label]
            translation_obj = translations.get(t.id, None)
            translation = {
                'label': filter_output["tagtranslations"][t.label] if t.label in filter_output["tagtranslations"] else t.label,
                'abstract': translation_obj.abstract if translation_obj else ""
            }
            
            content["nodes"].append({
              "id": unicode(uuid.uuid1()),
              "title": translation['label'],
              "description": translation['abstract'],
              "uri": t.wikipedia_url,
              "position": np.get_place("tags"),
              "image": img_url,
              "size": 0,
              "project_id": project_id,
              "color": None,
              #"created_by": "roster_user-84fe909f-ba37-48e6-a25f-9d2f129a95b7",
              "shape": shapes["tag1"]
            })
        if period:
            content["nodes"].append({
              "id": unicode(uuid.uuid1()),
              "title": _("Period") + " " + period,
              "description": "",
              "uri": "",
              "position": np.get_place("tags"),
              "image": cat_dict[u"Datation"],
              "size": 0,
              "project_id": project_id,
              "color": None,
              #"created_by": "roster_user-84fe909f-ba37-48e6-a25f-9d2f129a95b7",
              "shape": shapes["tag1"]
            })
        
        for c in filter_output["contents"]:
            content["nodes"].append({
              "id": c["id"],
              "title": c["title"],
              "description": c["description"],
              "uri": c["url"],
              "position": np.get_place("datasheet"),
              "image": "http://www.histoiredesarts.culture.fr/images/pf/" + c["hda_id"]+ ".jpg",
              "size": 0,
              "project_id": project_id,
              "color": "#FF0033",
              #"created_by": "roster_user-84fe909f-ba37-48e6-a25f-9d2f129a95b7",
              "shape": shapes["notice"]
            })
        
        for t in related_tags:
            translation_obj = translations.get(t['id'], None)
            translation = {
                'label': filter_output["tagtranslations"][t["label"]],
                'abstract': translation_obj.abstract if translation_obj else ""
            }

            content["nodes"].append({
              "id": t["id"],
              "title": translation['label'],
              "description": translation['abstract'],
              "uri": t["wkpd_url"],
              "position": np.get_place("related"),
              "image": t["thumbnail"],
              "size": 0,
              "project_id": project_id,
              "color": "#00FF33",
              #"created_by": "roster_user-84fe909f-ba37-48e6-a25f-9d2f129a95b7",
              "shape": shapes["tag2"]
            })
        
        for c_id in related_tags_dict:
            for tag_id in related_tags_dict[c_id]:
                content["edges"].append({
                    "id": unicode(uuid.uuid1()),
                    "title": "",
                    "description": "",
                    "uri": "",
                    "color": None,
                    "from": c_id,
                    "to": tag_id,
                    "project_id": project_id,
                    #"created_by": "de68xf75y6hs5rgjhgghxbm217xk"
                })
        
        response = json.dumps(content)
        
        return HttpResponse(response, content_type="application/json")
    
    
    def post(self, request):
        
        rk_id = request.GET.get("rk_id", "")
        #data = json.loads(request.body)
        #logger.debug(data["edges"])
        #logger.debug(data["nodes"])
        #logger.debug(request.user.is_authenticated())
        #logger.debug(request.user.is_anonymous())
        if rk_id!="":
            rk = get_object_or_404(Renkan, rk_id=rk_id)
            if rk.owner!=request.user:
                return HttpResponseBadRequest("You are not allowed to edit this renkan")
            rk.content = request.body
            data = json.loads(request.body)
            if "title" in data:
                rk.title = data["title"]
            rk.save()
            return HttpResponse("SAVED")
        else:
            # if rk_id was not a get parameter AND if it is set in json data AND if user is authenticated
            # Then we can save the renkan
            data = json.loads(request.body)
            if "id" in data:
                rk_id = data["id"]
                if rk_id != "" and Renkan.objects.filter(rk_id=rk_id).count()==0 and request.user.is_authenticated():
                    rk = Renkan()
                    rk.rk_id = rk_id
                    rk.title = data["title"] if "title" in data else ""
                    rk.content = request.body
                    rk.owner = request.user
                    rk.save()
                    hr = HdalabRenkan()
                    hr.renkan = rk
                    hr.state = HdalabRenkan.EDITION
                    hr.save()
                    return HttpResponse("rk_id=" + rk_id)
         
            
        return HttpResponse("NOT SAVED")



class HdalabRenkanCopy(View):
    
    def post(self, request, rk_id):
        rk = renkan_copier(request.user, rk_id)
        hr = HdalabRenkan()
        hr.renkan = rk
        hr.state = HdalabRenkan.EDITION
        hr.save()
        if "next" in request.POST:
            return redirect(request.POST["next"])
        return redirect(reverse('profile_home'))


class HdalabRenkanDelete(View):
    
    def post(self, request, rk_id):
        try:
            hr = HdalabRenkan.objects.get(renkan__rk_id=rk_id)
        except:
            raise Http404('Renkan not found')
        renkan_deleter(request.user, rk_id)
        hr.delete()
        if "next" in request.POST:
            return redirect(request.POST["next"])
        return redirect(reverse('profile_home'))


class HdalabRenkanModerate(View):
    
    def post(self, request, rk_id):
        form = HdalabRenkanStateForm(request.POST)
        if form.is_valid():
            logger.debug("FORM DATA %r", form.cleaned_data)
            renkan_hda =  get_object_or_404(HdalabRenkan.objects.select_related(), renkan__rk_id=rk_id)
            change_renkan_state(renkan_hda, form.cleaned_data['state'], form.cleaned_data['message'], request.user)
            next_url = form.cleaned_data.get('next', None)
            if next_url:
                return redirect(next_url)
            else:
                redirect(reverse('profile_home'))
        else:
            logger.debug("FORM INVALID %r : %r", request.POST, form.errors)
            return HttpResponseBadRequest("State form invalid")

class HdalabRenkanFavorite(View):
    
    def post(self, request, rk_id):
        form = HdalabRenkanFavoriteForm(request.POST)
        if form.is_valid():
            renkan_hda =  get_object_or_404(HdalabRenkan.objects.select_related(), renkan__rk_id=rk_id)
            renkan_hda.favorite = form.cleaned_data['favorite']
            renkan_hda.save()
            return HttpResponse(
                json.dumps({'status': 'ok', 'renkan': {'rk_id': renkan_hda.renkan.rk_id, 'favorite': renkan_hda.favorite}}),
                content_type="application/json"
            )


class UserProfileUpdate(UpdateView):
    model = User
    fields = ['email']
    template_name_suffix = '_update_form'

    def get_object(self, queryset=None):
        return self.request.user
    
    def get_success_url(self):
        return reverse('profile_home')
    

# Function copied from django.contrib.auth.views to simplify ajax login
@sensitive_post_parameters()
@csrf_protect
@never_cache
def ajax_login(request, template_name='ajax_identification/ajax_login.html',
          redirect_field_name=REDIRECT_FIELD_NAME,
          authentication_form=AuthenticationForm,
          current_app=None, extra_context=None):
    """
    Displays the login form and handles the login action.
    """
    redirect_to = request.REQUEST.get(redirect_field_name, '')

    if request.method == "POST":
        form = authentication_form(request, data=request.POST)
        if form.is_valid():

            # Ensure the user-originating redirection url is safe.
            if not is_safe_url(url=redirect_to, host=request.get_host()):
                redirect_to = resolve_url(settings.LOGIN_REDIRECT_URL)

            # Okay, security check complete. Log the user in.
            auth_login(request, form.get_user())

            return HttpResponseRedirect(redirect_to)
    else:
        form = authentication_form(request)

    current_site = get_current_site(request)

    context = {
        'form': form,
        redirect_field_name: redirect_to,
        'site': current_site,
        'site_name': current_site.name,
    }
    if extra_context is not None:
        context.update(extra_context)
    return TemplateResponse(request, template_name, context,
                            current_app=current_app)