#################################
#### Auteur : philipe Demaria
#### pour SACADO
#################################

from django.conf import settings # récupération de variables globales du settings.py
from django.shortcuts import render, redirect
from account.models import  Student, Teacher, User,Resultknowledge, Resultskill, Resultlastskill
from account.forms import StudentForm, TeacherForm, UserForm
from django.contrib.auth.forms import  AuthenticationForm
from django.forms.models import modelformset_factory
from django.forms import inlineformset_factory
from django.contrib.auth.decorators import  permission_required,user_passes_test, login_required
from django.http import JsonResponse , FileResponse
from django.core import serializers
from django.template.loader import render_to_string
from django.contrib import messages
from qcm.models import Folder , Parcours , Relationship
from qcm.views import get_teacher_id_by_subject_id, all_levels
from group.models import Group , Sharing_group
from socle.models import  Knowledge , Level , Skill , Waiting , Subject
from bibliotex.models import  Bibliotex , Exotex , Relationtex , Blacklistex
from bibliotex.forms import  BibliotexForm , ExotexForm , RelationtexForm
from django.views.decorators.csrf import csrf_exempt
from tool.consumers import *

import uuid
import time
import math
import json
import random
from datetime import datetime , timedelta
from django.db.models import Q
from django.core.mail import send_mail
from group.decorators import user_is_group_teacher
from qcm.decorators import user_is_parcours_teacher, user_can_modify_this_course, student_can_show_this_course , user_is_relationship_teacher, user_is_customexercice_teacher , parcours_exists , folder_exists
from account.decorators import user_can_create, user_is_superuser, user_is_creator , user_is_testeur
##############bibliothèques pour les impressions pdf  #########################
import os
from pdf2image import convert_from_path # convertit un pdf en autant d'images que de pages du pdf
from django.utils import formats, timezone
from io import BytesIO, StringIO
from django.http import  HttpResponse
from reportlab.pdfgen import canvas
from reportlab.lib import colors
from reportlab.lib.pagesizes import A4, inch, landscape , letter
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer, Image , PageBreak
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.colors import yellow, red, black, white, blue
from reportlab.pdfgen.canvas import Canvas
from reportlab.lib.utils import ImageReader
from reportlab.lib.enums import TA_JUSTIFY,TA_LEFT,TA_CENTER,TA_RIGHT
from html import escape
from operator import attrgetter
from itertools import chain
cm = 2.54
import os
import re
import pytz
import csv
import html
from general_fonctions import *
import subprocess

##################################################################################################################################
##################################################################################################################################
##################################################################################################################################
def affectation_students_folders_groups(nf,group_ids,folder_ids):

    all_students = set()
    all_levels, all_subjects = [] , []
    for group_id in group_ids :
        group = Group.objects.get(pk = group_id)
        group_students = group.students.all()
        all_students.update( group_students )
        all_levels.append(group.level)
        all_subjects.append(group.subject)

    nf.levels.set(all_levels)
    nf.students.set(all_students)
    nf.subjects.set(all_subjects)

    for folder_id in folder_ids:
        folder = Folder.objects.get(pk=folder_id)
        folder.groups.set(group_ids)

    return all_students

def printer(request, relationtex_id, collection,output):
    """affiche un exo ou une collection d'exercices, soit en pdf (output="pdf")
    soit en html (output="html") """

    # ouverture du texte dans le fichier tex

    if output=="pdf" :
        preamb = settings.TEX_PREAMBULE_PDF_FILE

    elif output == "html" or output == "html_cor" :
        preamb = settings.TEX_PREAMBULE_FILE

    entetes=open(preamb,"r")
    elements=entetes.read()
    entetes.close()

    elements +=r"\begin{document}"+"\n"

    ## Création du texte dans le fichier tex
    if relationtex_id == 0 : # 0 pour la méthode POST
        if collection :
            bibliotex_id = request.POST.get("print_bibliotex_id",None)
            bibliotex    = Bibliotex.objects.get(pk = bibliotex_id)
            document     = "bibliotex" + str(relationtex_id)
            title        = bibliotex.title
            author       = bibliotex.teacher.user.civilite+" "+bibliotex.teacher.user.last_name

        else :
            relationtex_id = request.POST.get("print_exotex_id",None)
            relationtex    =  Relationtex.objects.get(pk = relationtex_id)
            document       = "relationtex" + str(relationtex_id)
            title          =  relationtex.exotex.title
            author         = "Équipe SACADO"

        elements +=r"\titreFiche{"+title+r"}{"+author+r"}"

        skills_printer     = request.POST.get("skills",None)
        knowledges_printer = request.POST.get("knowledges",None)

        today = datetime.now()
        if collection :
            relationtexs = bibliotex.relationtexs.filter(Q( is_publish = 1 )|Q(start__lte=today , stop__gte= today)).order_by("ranking")
            i = 1
        else: relationtexs=[relationtex]

        j = 1
        for relationtex in relationtexs :

            skills_display = ""
            if skills_printer :
                if relationtex.skills.count():
                    sks =  relationtex.skills.all()
                else :
                    sks =  relationtex.exotex.skills.all()
                for s in sks :
                    skills_display +=  s.name+". "

            elements += r"\exo {\bf " +  relationtex.exotex.title  +  r" }    \competence{" +skills_display+r"}"

            j+=1

            if knowledges_printer :
                k_display = relationtex.exotex.knowledge.name
                elements += r"\savoirs{  \item " +  k_display

                if relationtex.knowledges.count()          : kws =  relationtex.knowledges.all()
                elif  relationtex.exotex.knowledges.count(): kws =  relationtex.exotex.knowledges.all()
                else : kws = []

                for k in kws :
                    elements += r" \item " +  k.name

                elements += r"}"

            if output == "html" or output== "html_cor" :
                if  relationtex.correction : ctnt =  relationtex.correction
                else                       : ctnt =  relationtex.exotex.correction
            else :
                if  relationtex.content : ctnt =  relationtex.content
                else                    : ctnt =  relationtex.exotex.content

            elements += ctnt
            elements += r"\vspace{0,4cm}\\"
    else : #pour la création d'un exercise ou son update*

        try :
            relationtex = Relationtex.objects.get(pk = relationtex_id)
            title       =  relationtex.exotex.title

            if output== "html_cor" :
                if  relationtex.correction : ctnt =  relationtex.correction
                else                       : ctnt =  relationtex.exotex.correction
            else :
                ctnt =  relationtex.exotex.content

        except :
            exotex         = Exotex.objects.get(pk = relationtex_id)
            title          =  exotex.title
            if output== "html_cor" :
                ctnt =  exotex.correction
            else :
                ctnt =  exotex.content

        document       = "relationtex" + str(relationtex_id)
        author         = "Équipe SACADO"

        elements += ctnt
        elements += r"\vspace{0,4cm}"
    # Fermeture du texte dans le fichier tex
    elements +=  r"\end{document}"

    elements +=  settings.DIR_TMP_TEX

    #################################################################
    ################################################################# Attention ERREUR si non modif
    # pour windows
    #file = settings.DIR_TMP_TEX+r"\\"+document
    # pour le serveur Linux
    file = settings.DIR_TMP_TEX+"/"+document
    #################################################################
    #################################################################

    f_tex = open(file+".tex","w")
    f_tex.write(elements)
    f_tex.close()

    if output=="pdf" :
        result = subprocess.run(["pdflatex", "-interaction","nonstopmode",  "-output-directory", settings.DIR_TMP_TEX ,  file ])
        return FileResponse(open(file+".pdf", 'rb'),  as_attachment=True, content_type='application/pdf')

    elif output == "html" or output== "html_cor" :
        #result = subprocess.run(["make4ht" ,  "-u" ,  file+".tex" , "mathml"] , cwd = settings.DIR_TMP_TEX )
        os.chdir(settings.DIR_TMP_TEX)
        os.system("make4ht -u "+document+".tex mathml")
        fhtml  = open(file+".html","r", errors='ignore')
        out    = ""
        recopie=False
        i=0
        for ligne in fhtml :
            ligne = ligne.replace('src="','src="https://sacado-academie.fr/ressources/tex/tmp_tex/')
            if "</body>" in ligne : recopie=False
            if recopie : out+=ligne
            if i  ==  9 : recopie=True
            i+=1
        return out

    else :
        print("format output non reconnu")
        return

def printer_bibliotex_by_student(bibliotex):
    """affiche un exo ou une collection d'exercices, en pdf (output="pdf") """

    # ouverture du texte dans le fichier tex

    preamb = settings.TEX_PREAMBULE_PDF_FILE

    entetes=open(preamb,"r")
    elements=entetes.read()
    entetes.close()

    elements +=r"\begin{document}"+"\n"

    ## Création du texte dans le fichier tex

    document     = "bibliotex" + str(bibliotex.id)
    title        = bibliotex.title
    author       = bibliotex.teacher.user.civilite+" "+bibliotex.teacher.user.last_name

    elements +=r"\titreFiche{"+title+r"}{"+author+r"}"

    today = datetime.now()

    relationtexs = bibliotex.relationtexs.filter(Q( is_publish = 1 )|Q(start__lte=today , stop__gte= today)).order_by("ranking")

    j = 1
    for relationtex in relationtexs :

        skills_display = ""
        if relationtex.skills.count():
            sks =  relationtex.skills.all()
        else :
            sks =  relationtex.exotex.skills.all()
        for s in sks :
            skills_display +=  s.name+". "

        elements += r"\exo {\bf " +  relationtex.exotex.title  +  r" }    \competence{" +skills_display+r"}"

        j+=1

        k_display = relationtex.exotex.knowledge.name
        elements += r"\savoirs{  \item " +  k_display

        if relationtex.knowledges.count()          : kws =  relationtex.knowledges.all()
        elif  relationtex.exotex.knowledges.count(): kws =  relationtex.exotex.knowledges.all()
        else : kws = []

        for k in kws :
            elements += r" \item " +  k.name

        elements += r"}"

        if  relationtex.content : ctnt =  relationtex.content
        else                    : ctnt =  relationtex.exotex.content

        elements += r"\vspace{0,2cm}\\"
        elements += ctnt
        elements += r"\vspace{0,4cm}\\"

    # Fermeture du texte dans le fichier tex
    elements +=  r"\end{document}"

    elements +=  settings.DIR_TMP_TEX

    #################################################################
    ################################################################# Attention ERREUR si non modif
    # pour windows
    #file = settings.DIR_TMP_TEX+r"\\"+document
    # pour le serveur Linux
    file = settings.DIR_TMP_TEX+"/"+document
    #################################################################
    #################################################################
    f_tex = open(file+".tex","w")
    f_tex.write(elements)
    f_tex.close()
    result = subprocess.run(["pdflatex", "-interaction","nonstopmode",  "-output-directory", settings.DIR_TMP_TEX ,  file ])
    return FileResponse(open(file+".pdf", 'rb'),  as_attachment=True, content_type='application/pdf')

#########################################################################################################################################
#########################################################################################################################################
######## Exotex
#########################################################################################################################################
#########################################################################################################################################

def admin_exotexs(request,idl):

    if request.user.is_superuser or request.user.is_extra :  # admin and more
        teacher = request.user.teacher
        level = Level.objects.get(pk=idl)
        exos = Exotex.objects.all()
        waitings = level.waitings.filter(theme__subject__in= teacher.subjects.all()).order_by("theme__subject" , "theme")

    return render(request, 'bibliotex/list_exotexs.html', { 'waitings': waitings, 'teacher':teacher , 'level':level   })

def my_exotexs(request):

    teacher = request.user.teacher
    exos = Exotex.objects.filter( Q(author=teacher)|Q(teachers=teacher) )
    return render(request, 'bibliotex/list_exotexs.html', {'exos': exos,  })

@user_passes_test(user_is_creator)
def create_exotex_knowledge(request,idk):

    knowledge = Knowledge.objects.get(id = idk)
    teacher = request.user.teacher
    form = ExotexForm(request.POST or None,request.FILES or None, teacher = teacher , knowledge = knowledge , initial={'author':teacher,'teachers':teacher,'knowledge':knowledge} )

    if form.is_valid():
        nf = form.save(commit = False)
        nf.author = teacher
        nf.teacher = teacher
        nf.save()

        save_html = True
        try :
            Exotex.objects.filter(pk= nf.id).update( content_html = printer(request, nf.id, False , "html" )   )
            if nf.correction :
                Exotex.objects.filter(pk= nf.id).update( correction_html = printer(request, nf.id, False , "html_cor" )   )
        except :
            save_html = False

        form.save_m2m()

        if save_html :
            messages.success(request, "L'exercice a été créé avec succès !")
        else :
            messages.error(request,"Le contenu html ne s'est pas enregistré. Modifier l'exercice et changer l'encodage.")

        return redirect('admin_exotexs', knowledge.level.id)
    else:
        print(form.errors)

    context = {'form': form, 'knowledge': knowledge , 'exotex': None }

    return render(request, 'bibliotex/form_exotex.html', context)

def set_exotex_in_bibliotex(request,id):

    bibliotex = Bibliotex.objects.get(id=id)
    teacher = request.user.teacher
    form = ExotexForm(request.POST or None,request.FILES or None, teacher = teacher , knowledge = None )

    if form.is_valid():
        nf = form.save(commit = False)
        nf.author = teacher
        nf.teacher = teacher
        nf.is_share = 1
        knowledges = request.POST.getlist("knowledge")
        nf.knowledge = Knowledge.objects.get(pk = knowledges[0])
        try :
            nf.knowledges.set(knowledges[1::])
        except :
            pass

        nf.save()

        save_html = True
        try :
            Exotex.objects.filter(pk= nf.id).update( content_html = printer(request, nf.id, False , "html" )   )
            if nf.correction :
                Exotex.objects.filter(pk= nf.id).update( correction_html = printer(request, nf.id, False , "html_cor" )   )
        except :
            save_html = False

        bibliotex.exotexs.add(nf)
        form.save_m2m()
        if save_html :
            messages.success(request, "L'exercice a été créé avec succès !")
        else :
            messages.error(request,"Le contenu html ne s'est pas enregistré. Modifier l'exercice et changer l'encodage.")

        return redirect('my_bibliotexs')
    else:
        print(form.errors)

    context = {'form': form, 'exotex': "init"  }

    return render(request, 'bibliotex/form_exotex.html', context)

def create_exotex(request):

    teacher = request.user.teacher
    form = ExotexForm(request.POST or None,request.FILES or None, teacher = teacher , knowledge = None )

    if form.is_valid():
        nf = form.save(commit = False)
        nf.author = teacher
        nf.teacher = teacher
        nf.is_share = 1
        nf.save()

        save_html = True
        try :
            Exotex.objects.filter(pk= nf.id).update( content_html = printer(request, nf.id, False , "html" )   )
            if nf.correction :
                Exotex.objects.filter(pk= nf.id).update( correction_html = printer(request, nf.id, False , "html_cor" )   )
        except :
            save_html = False

        form.save_m2m()

        if save_html :
            messages.success(request, "L'exercice a été créé avec succès !")
        else :
            messages.error(request,"Le contenu html ne s'est pas enregistré. Modifier l'exercice et changer l'encodage.")

        return redirect('admin_exotexs', nf.knowledge.level.id)
    else:
        print(form.errors)

    context = {'form': form, 'exotex': None  }

    return render(request, 'bibliotex/form_exotex.html', context)

def update_exotex(request, id):

    exotex = Exotex.objects.get(id=id)
    teacher = request.user.teacher
    form = ExotexForm(request.POST or None, request.FILES or None, instance=exotex , teacher = teacher , knowledge = exotex.knowledge )
    if request.method == "POST" :
        if form.is_valid():
            nf = form.save(commit = False)
            nf.author = teacher
            nf.teacher = teacher
            nf.save()
            form.save_m2m()

            save_html = True
            try :
                Exotex.objects.filter(pk= nf.id).update( content_html = printer(request, nf.id, False , "html" )   )
                if nf.correction :
                    Exotex.objects.filter(pk= nf.id).update( correction_html = printer(request, nf.id, False , "html_cor" )   )
            except :
                save_html = False

            if save_html :
                messages.success(request, "L'exercice a été créé avec succès !")
            else :
                messages.error(request,"Le contenu html ne s'est pas enregistré. Modifier l'exercice et changer l'encodage.")

            return redirect('admin_exotexs', exotex.knowledge.level.id)
        else:
            print(form.errors)

    context = {'form': form,  'exotex': exotex, 'knowledge': exotex.knowledge ,   }

    return render(request, 'bibliotex/form_exotex.html', context )

def delete_exotex(request, id):
    exotex = Exotex.objects.get(id=id)
    level_id = exotex.knowledge.level.id
    if request.user == exotex.author.user :
        exotex.delete()

    return redirect('admin_exotexs', level_id)

def update_relationtex(request, id):

    relationtex = Relationtex.objects.get(id=id)
    bibliotex_id = relationtex.bibliotex.id

    if relationtex.content : content = relationtex.content
    else : content = relationtex.exotex.content

    if relationtex.correction : correction = relationtex.correction
    else : correction = relationtex.exotex.correction

    teacher = request.user.teacher
    form = RelationtexForm(request.POST or None, request.FILES or None, instance = relationtex , teacher = teacher , initial = { 'content' : content , 'correction' : correction } )
    if request.method == "POST" :
        if form.is_valid():
            nf = form.save(commit = False)
            nf.teacher = teacher
            nf.save()
            form.save_m2m()

            Relationtex.objects.filter(pk= nf.id).update( content_html = printer(request, nf.id, False , "html" )   )
            if nf.correction :
                Relationtex.objects.filter(pk= nf.id).update( correction_html = printer(request, nf.id, False , "html_cor" )   )

            messages.success(request, "L'exercice a été modifié avec succès !")
            return redirect('show_bibliotex', bibliotex_id )
        else:
            print(form.errors)

    context = {'form': form,  'relationtex': relationtex,   }

    return render(request, 'bibliotex/form_relationtex.html', context )

def delete_relationtex(request, id):
    relationtex  = Relationtex.objects.get(id=id)
    bibliotex_id = relationtex.bibliotex.id

    if request.user == relationtex.teacher.user :
        relationtex.delete()

    return redirect('show_bibliotex', bibliotex_id)

#########################################################################################################################################
#########################################################################################################################################
######## Bibliotex
#########################################################################################################################################
#########################################################################################################################################
def bibliotexs(request):

    bibliotexs = Bibliotex.objects.all()
    teacher = request.user.teacher
    return render(request, 'bibliotex/all_bibliotexs.html', {'bibliotexs': bibliotexs,'teacher': teacher,   })

def my_bibliotexs(request):

    request.session["folder_id"] = None
    request.session["group_id"] = None
    teacher = request.user.teacher

    dataset_user = teacher.teacher_bibliotexs
    dataset      = dataset_user.filter(is_archive=0)

    bibliotexs = dataset.filter(folders=None)
    bibliotexs_folders = dataset.values_list("folders", flat=True).exclude(folders=None).distinct().order_by("folders")

    request.session["tdb"] = False # permet l'activation du surlignage de l'icone dans le menu gauche

    list_folders = list()
    for folder in bibliotexs_folders :
        bibtexs_folders = dict()
        bibtexs_folders["folder"] = Folder.objects.get(pk=folder)
        teacher_bibliotexs = dataset.filter(folders=folder)
        bibtexs_folders["bibliotexs"] = teacher_bibliotexs
        list_folders.append(bibtexs_folders)

    groups = teacher.has_groups() # pour ouvrir le choix de la fenetre modale pop-up

    request.session["tdb"] = False # permet l'activation du surlignage de l'icone dans le menu gauche

    nb_archive = dataset_user.filter(  is_archive=1).count()
    return render(request, 'bibliotex/list_bibliotexs.html', { 'list_folders': list_folders , 'bibliotexs': bibliotexs , 'teacher': teacher,  'groups': groups,   'nb_archive' : nb_archive  })

def my_bibliotex_archives(request):

    request.session["folder_id"] = None
    request.session["group_id"] = None
    teacher = request.user.teacher

    dataset = teacher.teacher_bibliotexs.filter(is_archive=1)

    bibliotexs = dataset.filter(folders=None)
    bibliotexs_folders = dataset.values_list("folders", flat=True).exclude(folders=None).distinct().order_by("folders")

    request.session["tdb"] = False # permet l'activation du surlignage de l'icone dans le menu gauche

    list_folders = list()
    for folder in bibliotexs_folders :
        bibtexs_folders = dict()
        bibtexs_folders["folder"] = Folder.objects.get(pk=folder)
        teacher_bibliotexs = dataset.filter(folders=folder)
        bibtexs_folders["bibliotexs"] = teacher_bibliotexs
        list_folders.append(bibtexs_folders)

    groups = teacher.has_groups() # pour ouvrir le choix de la fenetre modale pop-up

    request.session["tdb"] = False # permet l'activation du surlignage de l'icone dans le menu gauche

    return render(request, 'bibliotex/list_bibliotexs_archives.html', { 'list_folders': list_folders , 'bibliotexs': bibliotexs , 'teacher': teacher,  'groups': groups  })

def ajax_my_bibliotexs(request):

    level_id = request.POST.get("level_id")
    subject_id = request.POST.get("subject_id")

    teacher = request.user.teacher
    data = {}
    level =  Level.objects.get(pk = level_id)
    subject =  Subject.objects.get(pk = subject_id)
    bibliotexs = Bibliotex.objects.filter( Q(author=teacher)|Q(teacher=teacher)|Q(coteachers=teacher)  ,  subjects = subject   ,  levels = level ).distinct()

    data['html'] = render_to_string('bibliotex/ajax_list_bibliotexs.html', {'bibliotexs' : bibliotexs , })

    return JsonResponse(data)

def create_bibliotex_sequence(request,id):

    teacher = request.user.teacher
    folder_id = request.session.get("folder_id",None)
    group_id = request.session.get("group_id",None)
    if group_id :group = Group.objects.get(id=group_id)
    else : group = None
    if folder_id : folder = Folder.objects.get(id=folder_id)
    else : folder = None

    parcours = Parcours.objects.get(id=id)

    form = BibliotexForm(request.POST or None,request.FILES or None, teacher = teacher, folder = folder,  group = group, initial = { 'folders'  : [folder] ,  'groups'  : [group] ,  'parcours'  : [parcours]  } )

    if form.is_valid():
        nf = form.save(commit = False)
        nf.author = teacher
        nf.teacher = teacher
        nf.save()
        form.save_m2m()

        group_ids = request.POST.getlist("groups",[])
        folder_ids = request.POST.getlist("folders",[])
        nf.groups.set(group_ids)
        nf.folders.set(folder_ids)
        all_students = affectation_students_folders_groups(nf,group_ids,folder_ids)

        relation = Relationship.objects.create(parcours = parcours , exercise_id = None , document_id = nf.id  , type_id = 5 , ranking =  200 , is_publish= 1 , start= None , date_limit= None, duration= 10, situation= 0 )
        students = parcours.students.all()
        relation.students.set(students)

        return redirect('exercise_bibliotex_peuplate', nf.id)

    else:
        print(form.errors)

    context = {'form': form, 'bibliotex': None, 'folder': folder, 'group': group, 'parcours': parcours  }

    return render(request, 'bibliotex/form_bibliotex.html', context)

def ajax_find_peuplate_sequence(request):

    id_parcours = request.POST.get("id_parcours",0)
    subject_id  = request.POST.get("id_subject",0)
    level_id    = request.POST.get("id_level",None)
    keyword     = request.POST.get("keyword",None)

    level       = Level.objects.get(pk=level_id)
    subject     = Subject.objects.get(pk=subject_id)

    if keyword :
        bibliotexs  = Bibliotex.objects.filter( title__icontains=keyword,    teacher__user__school = request.user.school , subjects=subject,levels=level )
    else :
        bibliotexs  = Bibliotex.objects.filter(teacher__user__school = request.user.school , subjects=subject,levels=level )

    if keyword and level_id :
        level = Level.objects.get(pk=level_id)
        bibliotexs  = Bibliotex.objects.filter( title__icontains=keyword, teacher__user__school = request.user.school , subjects=subject,levels=level  )
    elif keyword :
        bibliotexs  = Bibliotex.objects.filter( title__icontains=keyword, teacher__user__school = request.user.school , subjects=subject  )
    else :
        level = Level.objects.get(pk=level_id)
        bibliotexs  = Bibliotex.objects.filter(teacher__user__school = request.user.school , subjects=subject ,levels=level )

    context = { "bibliotexs" : bibliotexs }

    data = {}
    data['html']    = render_to_string( 'bibliotex/ajax_bibliotex_peuplate_sequence.html' , context)

    return JsonResponse(data)

def clone_bibliotex_sequence(request, idb):
    """ cloner un parcours """

    teacher = request.user.teacher
    bibliotex = Bibliotex.objects.get(pk=idb) # parcours à cloner.pk = None
    relationtexs = bibliotex.relationtexs.all()
    bibliotex.pk = None
    bibliotex.teacher = teacher
    bibliotex.save()

    parcours_id = request.session.get("parcours_id",None)
    if parcours_id :
        parcours = Parcours.objects.get(pk = parcours_id)
        relation = Relationship.objects.create(parcours = parcours , exercise_id = None , document_id = bibliotex.id  , type_id = 5 , ranking =  200 , is_publish= 1 , start= None , date_limit= None, duration= 10, situation= 0 )
        students = parcours.students.all()
        relation.students.set(students)

    for r in relationtexs :
        r.pk = None
        r.teacher = teacher
        r.save()

        if parcours_id :
            r.students.set(students)

    return redirect('show_parcours' , 0, parcours_id )

def ajax_search_bibliotex(request):

    teacher = request.user.teacher
    data = {}

    level_id = request.POST.get('level_id',0)
    subject_id = request.POST.get('subject_id',None)

    teacher_id = get_teacher_id_by_subject_id(subject_id)

    if request.user.is_superuser :
        bibliotexs_ids = Bibliotex.objects.values_list("id",flat=True).distinct().filter(Q(teacher__user__school = teacher.user.school)| Q(teacher__user_id=teacher_id),is_share = 1).order_by('level','ranking')
    else :
        bibliotexs_ids = Bibliotex.objects.values_list("id",flat=True).distinct().filter(Q(teacher__user__school = teacher.user.school)| Q(teacher__user_id=teacher_id),is_share = 1).exclude(exotexs = None ,teacher=teacher).order_by('level','ranking')

    keywords = request.POST.get('keywords',None)

    if int(level_id) > 0 :
        level = Level.objects.get(pk=int(level_id))
        theme_ids = request.POST.getlist('theme_id',[])

        if len(theme_ids) > 0 :

            if theme_ids[0] != '' :

                print(theme_ids)

                if keywords :
                    bibliotexs = Bibliotex.objects.filter( Q(teacher__user_id=teacher_id)|Q(exotexs__content__icontains = keywords) |Q(teacher__user__first_name__icontains = keywords) |Q(teacher__user__last_name__icontains = keywords)  ,is_share = 1,
                                                        exotexs__knowledge__theme__in = theme_ids,  teacher__user__school = teacher.user.school,  levels = level ).exclude(teacher=teacher).order_by('teacher').distinct()
                else :
                    bibliotexs = Bibliotex.objects.filter(Q(teacher__user__school = teacher.user.school)| Q(teacher__user_id=teacher_id),is_share = 1,
                                                            exotexs__knowledge__theme_id__in = theme_ids, levels = level ).exclude(teacher=teacher).order_by('teacher').distinct()

            else :
                if keywords :
                    bibliotexs = Bibliotex.objects.filter(Q(teacher__user_id=teacher_id)|Q(teacher__user__first_name__icontains= keywords) |Q(teacher__user__last_name__icontains = keywords)   |Q(exotexs__content__icontains = keywords),is_share = 1,
                                                            teacher__user__school = teacher.user.school ,  levels = level  ).exclude(teacher=teacher).order_by('teacher').distinct()

                else :
                    bibliotexs = Bibliotex.objects.filter(Q(teacher__user__school = teacher.user.school)| Q(teacher__user_id=teacher_id),is_share = 1,
                                                            levels = level ).exclude(teacher=teacher).order_by('teacher').distinct()

        else :
            if keywords:
                bibliotexs = Bibliotex.objects.filter( Q(teacher__user_id=teacher_id)|Q(teacher__user__first_name__icontains = keywords) |Q(teacher__user__last_name__icontains = keywords)  |Q(exotexs__content__icontains = keywords),teacher__user__school = teacher.user.school,is_share = 1,
                                                        levels = level ).exclude(teacher=teacher).order_by('teacher').distinct()
            else :
                bibliotexs = Bibliotex.objects.filter(Q(teacher__user__school = teacher.user.school)| Q(teacher__user_id=teacher_id),is_share = 1,
                                                        levels = level ).exclude(teacher=teacher).order_by('teacher').distinct()
    else :
        if keywords:
            bibliotexs = Bibliotex.objects.filter(Q(teacher__user__school = teacher.user.school)| Q(teacher__user_id=teacher_id)|Q(teacher__user__first_name__icontains = keywords) |Q(teacher__user__last_name__icontains = keywords)  , is_share = 1 ,  exotexs__content__icontains = keywords ).exclude(teacher=teacher).order_by('author','ranking').distinct()
        else :
            bibliotexs = Bibliotex.objects.filter(Q(teacher__user__school = teacher.user.school)| Q(teacher__user_id=teacher_id),is_share = 1 ).exclude(teacher=teacher).order_by('teacher').distinct()

    data['html'] = render_to_string('bibliotex/ajax_list_bibliotexs.html', {'bibliotexs' : bibliotexs, 'teacher' : teacher ,  })

    return JsonResponse(data)

def create_bibliotex(request,idf=0):

    teacher = request.user.teacher
    folder_id = request.session.get("folder_id",idf)
    group_id = request.session.get("group_id",None)
    if group_id :
        group = Group.objects.get(id=group_id)
    else :
        group = None

    if folder_id :
        folder = Folder.objects.get(id=folder_id)
    else :
        folder = None

    form = BibliotexForm(request.POST or None,request.FILES or None, teacher = teacher, folder = folder, group = group,  initial = { 'folders'  : [folder] ,  'groups'  : [group] } )

    if form.is_valid():
        nf = form.save(commit = False)
        nf.author = teacher
        nf.teacher = teacher
        nf.save()
        form.save_m2m()

        group_ids = request.POST.getlist("groups",[])
        folder_ids = request.POST.getlist("folders",[])
        nf.groups.set(group_ids)
        nf.folders.set(folder_ids)
        all_students = affectation_students_folders_groups(nf,group_ids,folder_ids)

        return redirect('exercise_bibliotex_peuplate', nf.id)

    else:
        print(form.errors)

    context = {'form': form, 'bibliotex': None, 'folder': folder, 'group': group  }

    return render(request, 'bibliotex/form_bibliotex.html', context)

def update_bibliotex(request, id):

    teacher = request.user.teacher
    bibliotex = Bibliotex.objects.get(id=id)
    folder_id = request.session.get("folder_id",None)
    group_id = request.session.get("group_id",None)
    if group_id :
        group = Group.objects.get(id=group_id)
    else :
        group = None

    if folder_id :
        folder = Folder.objects.get(id=folder_id)
    else :
        folder = None

    form = BibliotexForm(request.POST or None, request.FILES or None, instance=bibliotex, teacher = teacher , folder = folder, group = group,  )

    if form.is_valid():
        nf = form.save(commit = False)
        nf.author = teacher
        nf.teacher = teacher
        nf.save()
        form.save_m2m()

        group_ids = request.POST.getlist("groups",[])
        folder_ids = request.POST.getlist("folders",[])
        nf.groups.set(group_ids)
        nf.folders.set(folder_ids)
        all_students = affectation_students_folders_groups(nf,group_ids,folder_ids)

        return redirect('exercise_bibliotex_peuplate', nf.id)

    else:
        print(form.errors)

    context = {'form': form, 'bibliotex': bibliotex,   }

    return render(request, 'bibliotex/form_bibliotex.html', context)

def create_bibliotex_from_parcours(request,idp=0):

    teacher = request.user.teacher
    folder_id = request.session.get("folder_id",None)
    group_id = request.session.get("group_id",None)
    if group_id :group = Group.objects.get(id=group_id)
    else : group = None
    if folder_id : folder = Folder.objects.get(id=folder_id)
    else : folder = None

    parcours = Parcours.objects.get(id=idp)

    form = BibliotexForm(request.POST or None,request.FILES or None, teacher = teacher, folder = folder,  group = group, initial = { 'folders'  : [folder] ,  'groups'  : [group] ,  'parcours'  : [parcours]  } )

    if form.is_valid():
        nf = form.save(commit = False)
        nf.author = teacher
        nf.teacher = teacher
        nf.save()
        form.save_m2m()

        group_ids = request.POST.getlist("groups",[])
        folder_ids = request.POST.getlist("folders",[])
        nf.groups.set(group_ids)
        nf.folders.set(folder_ids)
        all_students = affectation_students_folders_groups(nf,group_ids,folder_ids)

        return redirect('exercise_bibliotex_peuplate', nf.id)

    else:
        print(form.errors)

    context = {'form': form, 'bibliotex': None, 'folder': folder, 'group': group, 'parcours': parcours  }

    return render(request, 'bibliotex/form_bibliotex.html', context)

def peuplate_bibliotex_parcours(request,idp):

    teacher = request.user.teacher
    parcours = Parcours.objects.get(id=idp)
    bibliotexs = Bibliotex.objects.filter(parcours=parcours)

    context = {'parcours': parcours, 'teacher': teacher , 'bibliotexs' : bibliotexs , 'type_of_document' : 5 }

    return render(request, 'bibliotex/form_peuplate_bibliotex_parcours.html', context)

def delete_bibliotex(request, id):
    bibliotex = Bibliotex.objects.get(id=id)
    if request.user == bibliotex.author.user :
        bibliotex.delete()

    return redirect('bibliotexs')

def show_bibliotex(request, id):

    bibliotex = Bibliotex.objects.get(id=id)
    relationtexs = Relationtex.objects.filter(bibliotex_id=id).order_by("ranking")

    context = { 'bibliotex': bibliotex, 'relationtexs': relationtexs, }

    return render(request, 'bibliotex/show_bibliotex.html', context )

def actioner(request):

    teacher = request.user.teacher
    idbs = request.POST.getlist("selected_bibliotexs")
    if  request.POST.get("action") == "deleter" :
        for idb in idbs :
            bibliotex = Bibliotex.objects.get(id=idb)
            bibliotex.coteachers.clear()
            bibliotex.folders.clear()
            bibliotex.groups.clear()
            bibliotex.parcours.clear()
            bibliotex.exotexs.clear()
            bibliotex.students.clear()
            bibliotex.levels.clear()
            bibliotex.subjects.clear()
            bibliotex.delete()

    elif  request.POST.get("action") == "archiver" :
        for idb in idbs :
            bibliotex = Bibliotex.objects.get(id=idb)
            bibliotex.is_archive = 1
            bibliotex.is_favorite = 0
            bibliotex.save()

    else :
        for idb in idbs :
            bibliotex = Bibliotex.objects.get(id=idb)
            bibliotex.is_archive = 0
            bibliotex.is_favorite = 0
            bibliotex.save()

    return redirect('my_bibliotexs')

def ajax_publish_bibliotex(request):

    data = {}
    bibliotex_id = request.POST.get('bibliotex_id', None)
    statut = request.POST.get("statut")

    if statut == "True":
        data["statut"] = "False"
        data["publish"] = " n'est pas "
        data["class"] = "legend-btn-danger"
        data["noclass"] = "legend-btn-success"
        data["legendclass"] = "text-danger"
        data["nolegendclass"] = "text-success"
        data["color"] = "background-color:#dd4b39"
        data["removedisc"] = "disc"
        data["adddisc"] = "disc_persistant"
        data["noget"] = ""
        data["get"] = "noget"
        status = 0

    else:
        data["statut"] = "True"
        data["publish"] = "est"
        data["class"] = "legend-btn-success"
        data["noclass"] = "legend-btn-danger"
        data["legendclass"] = "text-success"
        data["nolegendclass"] = "text-danger"
        data["color"] = "background-color:#00a65a"
        data["removedisc"] = "disc_persistant"
        data["adddisc"] = "disc"
        data["get"] = "get"
        data["noget"] = ""
        status = 1

    Bibliotex.objects.filter(pk = int(bibliotex_id)).update(is_publish = status)
    return JsonResponse(data)

def exercise_bibliotex_results(request, id):

    bibliotex    = Bibliotex.objects.get(id=id)
    relationtexs = Relationtex.objects.filter(bibliotex_id=id)
    students     = bibliotex.students.exclude(user__username__contains="_e-test").order_by('user__last_name')

    context = { 'bibliotex': bibliotex, 'relationtexs': relationtexs, 'students' : students  }

    return render(request, 'bibliotex/bibliotex_results.html', context )

def exercise_bibliotex_peuplate(request, id):

    teacher   = request.user.teacher
    bibliotex = Bibliotex.objects.get(id=id)
    skills    = Skill.objects.filter(subject__in=teacher.subjects.all())
    relationtexs = bibliotex.relationtexs.order_by("ranking")

    context   = { 'bibliotex': bibliotex, 'relationtexs': relationtexs , 'teacher': teacher, 'skills' : skills  }

    return render(request, 'bibliotex/form_peuplate_bibliotex.html', context )

def  exercise_bibliotex_individualise(request, id):

    teacher   = request.user.teacher
    bibliotex = Bibliotex.objects.get(id=id)

    context   = { 'bibliotex': bibliotex,    'group':None }

    return render(request, 'bibliotex/form_individualise_bibliotex.html', context )

def real_time_bibliotex(request, id):
    pass

def  ajax_chargethemes(request):
    level_id =  request.POST.get("id_level")
    id_subject =  request.POST.get("id_subject")
    teacher = request.user.teacher

    teacher_id = get_teacher_id_by_subject_id(id_subject)

    data = {}
    level =  Level.objects.get(pk = level_id)

    thms = level.themes.values_list('id', 'name').filter(subject_id=id_subject).order_by("name")
    data['themes'] = list(thms)
    exotexs = Exotex.objects.filter(Q(author__user__school = teacher.user.school)| Q(author__user_id=teacher_id),  level_id = level_id ).order_by('author').distinct()

    data['html'] = render_to_string('qcm/ajax_list_parcours.html', {'exotexs' : exotexs , })

    return JsonResponse(data)

def ajax_level_exotex(request):

    data = {}

    theme_ids    = request.POST.getlist('theme_id', None)
    level_id     = request.POST.get("level_id",None)
    subject_id   = request.POST.get("subject_id",None)
    skill_id     = request.POST.get("skill_id",None)
    keyword      = request.POST.get("keyword",None)
    bibliotex_id = request.POST.get("bibliotex_id",None)
    is_annale    = request.POST.get("is_annale",None)

    teacher = request.user.teacher

    if int(level_id) > 0 and subject_id :
        level = Level.objects.get(pk=int(level_id))
        subject = Subject.objects.get(pk=int(subject_id))
        thms  = level.themes.values_list('id', 'name').filter(subject_id=subject_id).order_by("name")
        data['themes'] = list(thms)

    if bibliotex_id :

        bibliotex = Bibliotex.objects.get(pk=bibliotex_id)
        teacher = request.user.teacher

        data['knowledges']       =  None
        data['knowledges_level'] =  None

        base = Exotex.objects.filter(theme__subject_id = subject_id).exclude(bibliotexs=bibliotex)
        if is_annale == 'yes' :
            base = base.filter(is_annals=1)

        if level_id  :
            base = base.filter( level_id = level_id).order_by("theme","knowledge__waiting","knowledge","ranking")

        if skill_id  :
            skill = Skill.objects.get(pk=skill_id)
            base = base.filter( skills = skill ).order_by("theme","knowledge__waiting","knowledge","ranking")

        if theme_ids :
            knowledges = set()
            for theme_id in theme_ids :
                try :
                    theme = Theme.objects.get(pk=int(theme_id))
                    knowledges.update( theme.knowledges.values_list('id', 'name').filter(level_id = level_id ) )
                except :
                    knowledges = []
            data['knowledges']  =  list(knowledges)

            if theme_ids[0] != "" :
                base = base.filter( theme_id__in= theme_ids ).order_by("theme","knowledge__waiting","knowledge","ranking")

        if keyword  :
            base = base.filter(Q(title__icontains=keyword)| Q(content_html__icontains=keyword)).order_by("theme","knowledge__waiting","knowledge","ranking")

        exotexs = base

        data['html'] = render_to_string('bibliotex/ajax_list_exercises.html', { 'bibliotex_id': bibliotex_id , 'exotexs': exotexs , "teacher" : teacher  })

    else :
        knowledges = Knowledge.objects.values_list("id","name").filter(theme_id__in=theme_ids, level_id = level_id  )
        knowledges_level = Knowledge.objects.values_list("id","name").filter(theme__subject__id = subject_id,  level_id = level_id  )
        data['knowledges']       =  list( knowledges )
        data['knowledges_level'] =  list( knowledges_level )
    return JsonResponse(data)

def ajax_charge_folders(request):

    teacher = request.user.teacher
    data = {}
    group_ids = request.POST.getlist('group_ids', None)

    if len(group_ids) :
        fldrs = set()
        prcs  = set()
        for group_id in group_ids :
            group = Group.objects.get(pk=group_id)
            fldrs.update(group.group_folders.values_list("id","title").filter(is_trash=0))
            prcs.update(group.group_parcours.values_list("id","title").filter(is_trash=0,folders=None))
        data['folders'] =  list( fldrs )
        data['parcours'] =  list( prcs )
    else :
        data['folders'] =  []
        data['parcours'] =  []
    return JsonResponse(data)

def ajax_charge_parcours(request):

    teacher = request.user.teacher
    data = {}
    folder_ids = request.POST.getlist('folder_ids', None)

    if len(folder_ids) :
        parcourses = set()
        for folder_id in folder_ids :
            folder = Folder.objects.get(pk=folder_id)
            parcourses.update(folder.parcours.values_list("id","title").filter(is_trash=0))

        data['parcours'] =  list( parcourses )
    else :
        data['parcours'] =  []

    return JsonResponse(data)

def ajax_set_exotex_in_bibliotex(request):

    data = {}
    exotex_id    = request.POST.get('exotex_id', None)
    bibliotex_id = request.POST.get('bibliotex_id', None)

    bibliotex   = Bibliotex.objects.get(pk = bibliotex_id)
    exotex      = Exotex.objects.get(pk = exotex_id)
    skills      = exotex.skills.all()
    knowledges  = exotex.knowledges.all()

    statut = request.POST.get("statut")

    data = {}
    stds     = bibliotex.students.all()

    if statut=="true" or statut == "True":

        r = Relationtex.objects.get(bibliotex_id=bibliotex_id , exotex_id = exotex_id )
        students = list(stds)
        r.students.remove(*students)

        data["statut"] = "False"
        data["class"] = "btn btn-danger"
        data["noclass"] = "btn btn-success"

    else:
        try :
            relationtex = Relationtex.objects.create(   bibliotex_id=bibliotex_id, exotex_id = exotex_id, ranking = 100,
                                                        teacher = request.user.teacher, calculator = exotex.calculator,  duration =exotex.duration ,
                                                        is_python = exotex.is_python,is_scratch =exotex.is_scratch,is_tableur =exotex.is_tableur,is_print = 0,
                                                        is_publish = 1,  correction=exotex.correction ,is_publish_cor = 0 )
            relationtex.skills.set(skills)
            relationtex.knowledges.set(knowledges)
            relationtex.students.set(stds)

            data["statut"]  = "True"
            data["class"]   = "btn btn-success"
            data["noclass"] = "btn btn-danger"
        except :
            data["statut"] = "False"
            data["class"] = "btn btn-danger"
            data["noclass"] = "btn btn-success"

    data["nb"] = bibliotex.exotexs.count()

    return JsonResponse(data)

def unset_exotex_in_bibliotex(request,idr):
    bibliotex_id = Relationtex.objects.get(pk = idr).bibliotex.id
    Relationtex.objects.filter(pk = idr).delete()
    return redirect("show_bibliotex" , bibliotex_id)

@csrf_exempt # PublieDépublie un exercice depuis organize_parcours
def ajax_is_favorite(request):

    target_id = int(request.POST.get("target_id",None))
    statut = int(request.POST.get("statut"))
    status = request.POST.get("status")
    data = {}

    if statut :
        Bibliotex.objects.filter(pk = target_id).update(is_favorite = 0)
        data["statut"] = "<i class='fa fa-star text-default' ></i>"
        data["fav"] = 0
    else :
        Bibliotex.objects.filter(pk = target_id).update(is_favorite = 1)
        data["statut"] = "<i class='fa fa-star   text-is_favorite' ></i>"
        data["fav"] = 1

    return JsonResponse(data)

def ajax_affectation_to_group(request):
    group_id    = request.POST.get('group_id')
    status      = request.POST.get('status')
    target_id   = request.POST.get('target_id')
    checked     = request.POST.get('checked')

    group       = Group.objects.get(pk=group_id)
    data        = {}
    html        = ""
    change_link = "no"

    bibliotex   = Bibliotex.objects.get(pk=target_id)
    if checked == "false" :
        bibliotex.groups.remove(group)
    else :
        bibliotex.groups.add(group)
        groups = (group,)
        attribute_all_documents_of_groups_to_all_new_students(groups)
    for g in bibliotex.groups.all():
        html += "<small>"+g.name +" (<small>"+ str(g.just_students_count())+"</small>)</small> "
    change_link = "change"

    data['html']        = html
    data['change_link'] = change_link
    return JsonResponse(data)

@csrf_exempt   # PublieDépublie un parcours depuis form_group et show_group
def ajax_sharer_parcours(request):

    parcours_id = request.POST.get("parcours_id")
    statut = request.POST.get("statut")
    is_folder = request.POST.get("is_folder")

    data = {}
    if statut=="true" or statut == "True":
        statut = 0
        data["statut"]  = "false"
        data["share"]   = "Privé"
        data["style"]   = "#dd4b39"
        data["class"]   = "legend-btn-danger"
        data["noclass"] = "legend-btn-success"
        data["label"]   = "Privé"
    else:
        statut = 1
        data["statut"]  = "true"
        data["share"]   = "Mutualisé"
        data["style"]   = "#00a65a"
        data["class"]   = "legend-btn-success"
        data["noclass"] = "legend-btn-danger"
        data["label"]   = "Mutualisé"

    Bibliotex.objects.filter(pk = int(parcours_id)).update(is_share = statut)

    return JsonResponse(data)

@csrf_exempt   # PublieDépublie un parcours depuis form_group et show_group
def ajax_publish_list_bibliotex(request):

    bibliotex_id = request.POST.get("bibliotex_id")
    statut = request.POST.get("statut")
    data = {}
    if statut=="true" or statut == "True":
        statut = 0
        data["statut"] = "false"
        data["style"] = "#dd4b39"
        data["class"] = "legend-btn-danger"
        data["noclass"] = "legend-btn-success"
        data["label"] = "Non publié"
    else:
        statut = 1
        data["statut"] = "true"
        data["style"] = "#00a65a"
        data["class"] = "legend-btn-success"
        data["noclass"] = "legend-btn-danger"
        data["label"] = "Publié"

    Bibliotex.objects.filter(pk = int(bibliotex_id)).update(is_publish = statut)

    return JsonResponse(data)

############################################################################################################
############################################################################################################
#################  Résultats
############################################################################################################
############################################################################################################

def ajax_sort_exotexs_in_bibliotex(request):

    data = {}
    bibliotex_id = request.POST.get('bibliotex_id', None)
    relationtexs = request.POST.getlist('relationtexs', None)
    i=0
    for relationtex in relationtexs :
        Relationtex.objects.filter(pk = relationtex ).update(ranking=i)
        i+=1
    return JsonResponse(data)

############################################################################################################
############################################################################################################
#################  Résultats
############################################################################################################
############################################################################################################

def ajax_results_exotex(request):

    data = {}
    relationtex_id = request.POST.get('relationtex_id', None)
    relationtex = Relationtex.objects.get(pk=relationtex_id)
    students = relationtex.bibliotex.students.exclude(user__username__contains="_e-test").order_by("user__last_name")
    std_r = relationtex.students.order_by("user__last_name")
    if std_r.count() :
        students = [ s for s in std_r if s in students]

    context = { 'students': students , 'bibliotex': relationtex.bibliotex , "exotex" : relationtex.exotex  }
    data["html"] = render_to_string('bibliotex/ajax_results_exercise.html', context )
    data["title"] = "Résultats de l'exercice "+relationtex.exotex.title

    return JsonResponse(data)

############################################################################################################
############################################################################################################
#################  Individualisation
############################################################################################################
############################################################################################################

def ajax_individualise(request):
    """ A partir d'une bibliotex """
    data = {}
    relationtex_id = request.POST.get('relationtex_id', None)
    student_id     = request.POST.get('student_id', None)
    statut         = request.POST.get('statut', None)
    is_checked     = request.POST.get('is_checked', None)

    relationtex    = Relationtex.objects.get(pk=relationtex_id)

    if is_checked == "true" : # Pour tous lex exercices à partir du premier
        for relationtex in relationtex.relationtexs.filter(is_publish=1 ) :
            if student_id ==  "0"  :
                if statut=="true" or statut == "True" :
                    somme = 0
                    try :
                        for s in parcours.students.all() :
                            exercise = Exercise.objects.get(pk = exercise_id )
                            if Studentanswer.objects.filter(student = s , exercise = exercise, parcours = relationship.parcours).count() == 0 :
                                relationship.students.remove(s)
                                somme +=1
                            Blacklist.objects.get_or_create(customexercise=None, student = s ,relationship = relationship   )
                    except :
                        pass

                    data["statut"] = "False"
                    data["class"] = "btn btn-default"
                    data["noclass"] = "btn btn-success"
                    if somme == 0 :
                        data["alert"] = True
                    else :
                        data["alert"] = False

                else :
                    relationship.students.set(parcours.students.all())
                    for s in parcours.students.all():
                        if Blacklist.objects.filter(relationship=relationship, student = s ).count() > 0 :
                            Blacklist.objects.get(relationship=relationship, student = s ).delete()
                    data["statut"] = "True"
                    data["class"] = "btn btn-success"
                    data["noclass"] = "btn btn-default"
                    data["alert"] = False

            else :
                student = Student.objects.get(pk = student_id)

                if statut=="true" or statut == "True":

                    if Studentanswer.objects.filter(student = student , relationtex = relationtex ).count() == 0 :
                        relationship.students.remove(student)
                        Blacklist.objects.get_or_create(relationtex=relationtex, student = student  )
                        data["statut"] = "False"
                        data["class"] = "btn btn-default"
                        data["noclass"] = "btn btn-success"
                        data["alert"] = False

                    else :
                        data["statut"] = "True"
                        data["class"] = "btn btn-success"
                        data["noclass"] = "btn btn-default"
                        data["alert"] = True

                else:
                    relationship.students.add(student)
                    if Blacklist.objects.filter(relationtex=relationtex, student = student  ).count()  > 0 :
                        Blacklist.objects.get(relationtex=relationtex, student = student ).delete()
                    data["statut"] = "True"
                    data["class"] = "btn btn-success"
                    data["noclass"] = "btn btn-default"
                    data["alert"] = False
    else :
        if student_id ==  "0"  :
            if statut=="true" or statut == "True" :
                somme = 0
                try :
                    for s in relationtex.students.all() :
                        Blacklistex.objects.get_or_create(student = s , relationtex = relationtex   )
                except :
                    pass

                data["statut"] = "False"
                data["class"] = "btn btn-default"
                data["noclass"] = "btn btn-success"
                if somme == 0 :
                    data["alert"] = True
                else :
                    data["alert"] = False

            else :
                relationtex.students.set(relationtex.bibliotex.students.all())
                for s in relationtex.bibliotex.students.all():
                    if Blacklistex.objects.filter(relationtex=relationtex, student = s ).count() > 0 :
                        Blacklistex.objects.get(relationtex=relationtex, student = s ).delete()
                data["statut"] = "True"
                data["class"] = "btn btn-success"
                data["noclass"] = "btn btn-default"
                data["alert"] = False

        else :
            student = Student.objects.get(pk = student_id)

            if statut=="true" or statut == "True":

                relationtex.students.remove(student)
                Blacklistex.objects.get_or_create(relationtex=relationtex, student = student  )
                data["statut"] = "False"
                data["class"] = "btn btn-default"
                data["noclass"] = "btn btn-success"
                data["alert"] = False

            else:
                relationtex.students.add(student)
                if Blacklistex.objects.filter(relationtex=relationtex, student = student ).count()  > 0 :
                    Blacklistex.objects.get(relationtex=relationtex, student = student  ).delete()
                data["statut"] = "True"
                data["class"] = "btn btn-success"
                data["noclass"] = "btn btn-default"
                data["alert"] = False

    return JsonResponse(data)

def ajax_individualise_exotex(request):
    """ A partir d'un exotex """
    data = {}
    relationtex_id = request.POST.get('relationtex_id', None)
    relationtex = Relationtex.objects.get(pk=relationtex_id)
    students = relationtex.bibliotex.students.exclude(user__username__contains="_e-test").order_by("user__last_name")
    std_r = relationtex.students.all()
    if std_r.count() :
        students = std_b.intersection(std_r).order_by("user__last_name")
    context = { 'students': students ,  "relationtex" : relationtex }
    data["html"] = render_to_string('bibliotex/ajax_individualise_exercise.html',context)
    data["title"] = "Individualiser l'exercice "+relationtex.exotex.title

    return JsonResponse(data)
############################################################################################################
############################################################################################################
#################   IMPRESSION
############################################################################################################
############################################################################################################

def ajax_print_exotex(request):

    data = {}
    relationtex_id = request.POST.get('relationtex_id', None)
    relationtex = Relationtex.objects.get(pk=relationtex_id)
    context = { 'bibliotex': relationtex.bibliotex , "exotex" : relationtex.exotex  }
    data["html"] = render_to_string('bibliotex/ajax_print_exercise.html', context)
    data["title"] = "Imprimer l'exercice "+relationtex.exotex.title

    return JsonResponse(data)

def ajax_print_bibliotex(request):

    data = {}
    relationtex_id = request.POST.get('relationtex_id', None)
    bibliotex = Bibliotex.objects.get(pk=relationtex_id)
    students =  bibliotex.students.exclude(user__username__contains="_e-test").order_by("user__last_name")
    context = { 'students': students , 'bibliotex':  bibliotex   }
    data["html"] = render_to_string('bibliotex/ajax_print_bibliotex.html', context)
    data["title"] = "Imprimer la Bibliotex "+bibliotex.title

    return JsonResponse(data)

def print_bibliotex(request ):

    return printer(request,0, True,"pdf")

def print_exotex(request):

    return printer(request,0, False,"pdf")

def print_bibliotex_by_student(request,id):

    data = {}
    bibliotex = Bibliotex.objects.get(pk=id)
    return printer_bibliotex_by_student(bibliotex)

def annales(request, idl):

    level = Level.objects.get(pk=idl)
    bibliotexs = Bibliotex.objects.filter( levels = level, is_annal =1 )

    context = {'bibliotexs': bibliotexs,  }

    return render(request, 'bibliotex/annales.html', context)

def show_this_annale(request, idb):

    bibliotex    = Bibliotex.objects.get(pk=idb)
    relationtexs = bibliotex.relationtexs.order_by("ranking")

    context = { 'bibliotex': bibliotex  ,  'relationtexs': relationtexs,  }

    return render(request, 'bibliotex/show_this_annale.html', context)


import cv2
import dlib

# Function to calculate the focal length of the camera
def FocalLength(measured_distance, real_width, width_in_ref_image):
    focal_length = (width_in_ref_image * measured_distance)/ real_width
    return focal_length

# Distance estimation function
def Distance_finder (Focal_Length, real_face_width, face_width_in_frame):
    distance = (real_face_width * Focal_Length)/face_width_in_frame
    return distance

# Face Detection by Haar-Cascade
face_detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")

# For width of the face in frame
def face_data(image):
    face_width = 0
    gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    faces = face_detector.detectMultiScale(gray_image, 1.3, 5)
    for (x, y, h, w) in faces:
        cv2.rectangle(image, (x, y), (x+w, y+h), (222,141,123), 1)
        face_width = w
    return face_width

# For capturing distance from camera
def displaying_distance(cap):
    # video = cv2.VideoCapture(0)
    previous_distance = 30
    width = 14.3

    # To compare the distance we need another image
    img = cv2.imread("pic.jpg")
    face_width = face_data(img)
    Focal_length = FocalLength(previous_distance, width,face_width)
    print("Focal length : ", Focal_length)

    # k = True
    while True:
        ret, frame = cap.read()

        # while (k==True):

        #     k=False
        #     break

        if ret==True:
            face_width_in_frame = face_data(frame)
            if face_width_in_frame !=0:
                Distance = round(Distance_finder(Focal_length, width,face_width_in_frame),2)
                cv2.putText(frame, "Distance from Camera "+"{}".format(Distance)+"CM", (50,50), cv2.FONT_HERSHEY_COMPLEX,1, (123,246,123),3)

        cv2.imshow("frame", frame )
        if cv2.waitKey(1)==27:
            break

    cap.release()
    cv2.destroyAllWindows()
    # print("Distance captured : ", Distance)
    # return Distance


import numpy as np
import pandas as pd
import tensorflow.keras.backend as K

pred1 = pd.read_csv('C:/data/dacon_mnist2/anwsers/sub1.csv')
pred2 = pd.read_csv('C:/data/dacon_mnist2/anwsers/sub2.csv')
pred3 = pd.read_csv('C:/data/dacon_mnist2/anwsers/sub3.csv')

submission = pd.read_csv('C:/data/dacon_mnist2/sample_submission.csv')
submission.head()

pred1 = pred1.iloc[:,0:-1]
pred2 = pred2.iloc[:,0:-1]
pred3 = pred3.iloc[:,0:-1]
print(pred3)
sumsum = pd.concat([pred1, pred2, pred3], axis=1)

'''
submission['a', 'b', 'c', 'd', 'e',
     'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
     'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
     'x', 'y', 'z'] = pred1
submission['a', 'b', 'c', 'd', 'e',
     'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
     'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
     'x', 'y', 'z'] = pred2
submission['a', 'b', 'c', 'd', 'e',
     'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
     'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
     'x', 'y', 'z'] = pred3
'''
from collections import Counter
for i in range(sumsum.shape[0]) :
    predicts = sumsum.loc[i, : ]
    sub = Counter(predicts).most_common(n=25)[0][0]

'''
    submission.at[i, 'a', 'b', 'c', 'd', 'e',
     'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
     'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
     'x', 'y', 'z'] = Counter(predicts).most_common(n=25)#[0][0]
'''

# print(submission.head())

submission = submission[['index',  'a', 'b', 'c', 'd', 'e',
     'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
     'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
     'x', 'y', 'z']]
print(submission.head())

submission.to_csv('C:/data/dacon_mnist2/anwsers/merge1.csv', index=False)


from django.shortcuts import render
from blog import models
from django.core.paginator import Paginator, EmptyPage,PageNotAnInteger #自动分页包

# Create your views here.

def index(request):
    fenlei = models.Category.objects.all()
    img = models.Banner.objects.filter(is_active=True)
    tags = models.Tag.objects.all()
    tuijian = models.Article.objects.filter(tui__id=1)[:3]
    tuijian2 = models.Article.objects.filter(tui__id=2)[:3]
    allarticle = models.Article.objects.all().order_by('-id')[0:4]
    Url = models.Link.objects.all()
    hot = models.Article.objects.all().order_by('-views')[:5]
                            # 通过浏览数进行排序,加个 - 由高到低排序
    content = {
        'A': fenlei,
        'B': img,
        'D': tags,
        'Url': Url,
        'E': tuijian,
        'F': tuijian2,
        'new': allarticle,
        'hot': hot
    }
    return render(request, 'index.html', content, )

#列表页
def list(request,lid):
    fenlei = models.Category.objects.all()
    weizhi1 = models.Category.objects.get(pk=lid)
    wenzhang = models.Article.objects.filter(category__id=lid).order_by('-id')
    tags = models.Tag.objects.all()
    tuijian = models.Article.objects.filter(tui__id=2)[:3]
    Tag = models.Tag.objects.filter(article__id=lid)
    hot = models.Article.objects.all().order_by('-views')[:5]
                            # 通过浏览数进行排序,加个 - 由高到低排序

    page = request.GET.get('page')  # 在URL中获取当前页面数
    paginator = Paginator(wenzhang, 2)  # 对查询到的数据对象list进行分页，设置超过5条数据就分页
    try:
        wenzhang = paginator.page(page)  # 获取当前页码的记录
    except PageNotAnInteger:
        wenzhang = paginator.page(1)  # 如果用户输入的页码不是整数时,显示第1页的内容
    except EmptyPage:
        wenzhang = paginator.page(paginator.num_pages)  # 如果用户输入的页数不在系统的页码列表中时,显示最后一页的内容

    content = {
        'A': fenlei,
        'weizhi': weizhi1,
        'C': wenzhang,

        'D': tags,
        'F': tuijian,
        'Tag': Tag,
        'hot': hot,
    }
    return render(request,'list.html',content,)

#内容页
def show(request,sid):
    fenlei = models.Category.objects.all() # 键A,base页面的，所有分类
    category_id = models.Article.objects.get(pk=sid).category_id  #取出文章的id所对应的的分类表id
    weizhi1 = models.Category.objects.get(pk=category_id) #利用文章id-分列表id取出文章所属的分类，键weizhi1 (您的位置： 首页 » weizhi1 » 正文)
    body = models.Article.objects.get(pk=sid) #show页面取出文章的具体内容，使用 {{ body.body|safe }} 取出富文本编辑器的内容
    tags = models.Tag.objects.all() #键D，侧边栏的所有标签
    tuijian = models.Article.objects.filter(tui__id=2)[:3]  #键F，侧边栏的热门推荐
    wenzhang = models.Article.objects.get(pk=sid)  #取出sid对应的文章所有信息
    fenlei2 = models.Article.objects.get(pk=sid).category #{{ weizhi1 }} 跳转链接用
    category_id2 = models.Article.objects.get(pk=sid).category_id   #根据文章id取出文章对应的分类ID
    tonglei = models.Article.objects.filter(category_id=category_id2)  #根据文章的分类ID，过滤和他同类的文章信息
    user_id = models.Article.objects.get(pk=sid).user_id  #取出文章的User_id
    user = models.User.objects.get(pk=user_id).username  #取出文章的具体作者
    Tag = models.Tag.objects.filter(article__id=sid)  #键Tag，取出文章所属于的所有标签
    body.views = body.views + 1 #对访问量 + 1
    body.save() #保存
    hot = models.Article.objects.all().order_by('-views')[:5]
                        #通过浏览数进行排序,加个 - 由高到低排序
    previous_blog = models.Article.objects.filter(created_time__gt=body.created_time, category=body.category.id).first()
    #前一偏
    next_blog = models.Article.objects.filter(created_time__lt=body.created_time, category=body.category.id).last()
    #后一偏

    content = {
        'A': fenlei,
        'weizhi1': weizhi1,
        'wenzhang': wenzhang,
        'body': body,
        'tonglei': tonglei,
        'D': tags,
        'F': tuijian,
        'fenlen2': fenlei2,
        'username': user,
        'Tag': Tag,
        'hot': hot,
        'syp': previous_blog,
        'next': next_blog,
    }
    return render(request,'show.html',content)

#标签页
def tag(request, tag):
    tag_id = models.Tag.objects.get(name=tag)
    fenlei = models.Category.objects.all()
    wenzhang = models.Article.objects.filter(tags=tag_id).order_by('-id')
    tags = models.Tag.objects.all()
    tuijian = models.Article.objects.filter(tui__id=2)[:3]
    hot = models.Article.objects.all().order_by('-views')[:5]

    page = request.GET.get('page')  # 在URL中获取当前页面数
    paginator = Paginator(wenzhang, 2)  # 对查询到的数据对象list进行分页，设置超过5条数据就分页
    try:
        wenzhang = paginator.page(page)  # 获取当前页码的记录
    except PageNotAnInteger:
        wenzhang = paginator.page(1)  # 如果用户输入的页码不是整数时,显示第1页的内容
    except EmptyPage:
        wenzhang = paginator.page(paginator.num_pages)  # 如果用户输入的页数不在系统的页码列表中时,显示最后一页的内容
    content = {
        'A': fenlei,
        'wenzhang': wenzhang,
        'D': tags,
        'F': tuijian,
        'tag_id': tag_id,
        'Tag': tag,
        'hot': hot,
    }
    return render(request,'tag.html',content)

# 搜索页
def search(request):
    fenlei = models.Category.objects.all()  # 键A,base页面的，所有分类
    guanjianci = request.GET.get('search') #获取搜索的关键词
    list = models.Article.objects.filter(title__icontains=guanjianci) #获取到搜索关键词公国标题比配
    remen = models.Article.objects.filter(tui__id=2)[:6]
    allcategory = models.Category.objects.all()
    page = request.GET.get('page')
    tags = models.Tag.objects.all()
    tuijian = models.Article.objects.filter(tui__id=2)[:3]
    hot = models.Article.objects.all().order_by('-views')[:5]
    paginator = Paginator(list, 2) #每一页最多显示的文章数量
    try:
        list = paginator.page(page) # 获取当前页码的记录
    except PageNotAnInteger:
        list = paginator.page(1)  # 如果用户输入的页码不是整数时,显示第1页的内容
    except EmptyPage:
        list = paginator.page(paginator.num_pages)   # 如果用户输入的页数不在系统的页码列表中时,显示最后一页的内容

    content = {
        'A': fenlei,
        'guanjianci': guanjianci,
        'list': list, #分页用
        'remen': remen,
        'allcategory': allcategory,
        'page': page,
        'D': tags,
        'F': tuijian,
        'hot': hot,
    }
    return render(request, 'search.html', content)

# 关于我们
def about(request):
    fenlei = models.Category.objects.all()
    content = {
        'A': fenlei,
    }
    return render(request,'page.html',content)


#!/usr/bin/python3
"""
Pings a To-Do API for data and displays tasks completed
and tasks done for a specified user
"""
import requests
from sys import argv

if __name__ == '__main__':
    user_id = argv[1]
    user = requests.get("https://jsonplaceholder.typicode.com/users/{}".
                        format(user_id), verify=False).json()
    todo = requests.get("https://jsonplaceholder.typicode.com/todos?userId={}".
                        format(user_id), verify=False).json()

    completed_tasks = []
    for task in todo:
        if task.get('completed') is True:
            completed_tasks.append(task.get('title'))
    print("Employee {} is done with tasks({}/{}):"
          .format(user.get('name'), len(completed_tasks), len(todo)))

    for task in completed_tasks:
        print("\t {}".format(task))


import joblib
import pandas as pd
from shiny import ui
from _utils import *

__all__ = ["user_input_select",
           "output_model"]

MODEL_PATH = 'model/nn_model.joblib'
NORM_PATH = 'model/normalization.joblib'

model = joblib.load(MODEL_PATH)
normalizer = joblib.load(NORM_PATH)

def user_input_select():
    return ui.panel_sidebar(ui.input_slider("age", "AGE", min=age["min"], max=age["max"], value=age["value"]),
                            ui.input_select("workclass", "WORKCLASS", workclass),
                            ui.input_select("education", "EDUCATION", education),
                            ui.input_radio_buttons("marital_status", "MARITAL STATUS", marital_status),
                            ui.input_select("occupation", "OCCUPATION", occupation),
                            ui.input_select("relationship", "RELATIONSHIP", relationship),
                            ui.input_radio_buttons("race", "RACE", race),
                            ui.input_select("gender", "GENDER", gender),
                            ui.input_numeric("capital_gain", "CAPTITAL GAIN",
                                             cap_gain["value"], min=cap_gain["min"], max=cap_gain["max"]),
                            ui.input_numeric("capital_loss", "CAPTITAL LOSS",
                                             cap_loss["value"], min=cap_loss["min"], max=cap_loss["max"]),
                            ui.input_numeric("hours_week", "HOURS PER WEEK",
                                             hp_week["value"], min=hp_week["min"], max=hp_week["max"]),
                            ui.input_select("native_country", "NATIVE_COUNTRY", native_country),
                            ui.input_action_button("btn", "INCOME?", class_="btn-success")
                            )

def output_model(df: pd.DataFrame):

    # convert to dummy variables
    category_columns = list(df.select_dtypes(include=['category', 'object']).columns)
    other_columns = list(df.select_dtypes(exclude=['category', 'object']).columns)

    df_dummy = pd.get_dummies(df[category_columns], drop_first=False, dtype=float)

    df_num = df[other_columns]
    df = pd.concat([df_num, df_dummy], axis=1)
    del df_dummy, df_num

    # all columns - add other of dummy features
    train_columns = list(normalizer.feature_names_in_)
    add_col = [col for col in train_columns if col not in df.columns]

    for col in add_col:
        df[col] = 0  # se incluye con valor a cero

    df = df[train_columns]  # la muestra a predecir con el mismo orden que la muestra de entrenamiento

    # normalize variables
    X = normalizer.transform(df)

    # getting prediction
    # redes convolucionales - se añade una dimensión a los datos
    X = X.reshape(X.shape[0], X.shape[1], 1)
    prediction_proba = model.predict(X)

    output1 = round(prediction_proba[0][0] * 100, 2)
    pred = f"{str(output1)} %"
    return pred


from curie.models import base
from curie.loaders import arxiv, offline
from curie.cleaners import nltk
from curie.embedders.w2v import CW2V

from tqdm import tqdm

class ArxivCurie(base.AbstractModel):

    __name__ = "ArxivCurie"

    def __init__(self):
        super().__init__()
        self._loader = arxiv.ArxivReader()
        self._cleaner = nltk.NLTKCleaner()
        self._embedder = CW2V()

    @property
    def loader(self):
        return self._loader

    @property
    def cleaner(self):
        return self._cleaner

    @property
    def embedder(self):
        return self._embedder

    @property
    def summarizer(self):
        pass

    @property
    def name(self):
        return self.__name__

    def online_training(
        self, query: str, max_results=1000, epochs=5, load_kwargs={}
    ) -> None:
        self._loader.query(query, max_results, **load_kwargs)
        for paper in tqdm(self._loader.retrieve()):
            # extract sentences from paper, and clean
            text = self._cleaner.tokenize_sentence(paper)
            self._embedder.build_vocab(text, update=True)
            self._embedder.train(text, epochs=epochs, total_examples=len(text))

    def offline_training(self, path: str, epochs=3) -> None:
        """
        Function to perform the training routine using downloaded PDFs.
        This function overrides the `Loader` class the model would otherwise
        be using in favor of an `OfflineReader`, that simply loads and parses
        PDFs with `tika`.

        For every paper, we run the text through the cleaning pipeline, then
        pass it to our `Word2Vec` wrapper to train with.

        Parameters
        ----------
        path : str
            [description]
        """
        loader = offline.OfflineReader()
        paths = loader.query(path)
        for paper in tqdm(loader.retrieve(paths)):
            text = self._cleaner.tokenize_sentence(paper)
            self._embedder.build_vocab(text, update=True)
            self._embedder.train(text, epochs=epochs, total_examples=len(text))

    def summarize_pdf(self, path: str) -> str:
        text = self._loader.read_pdf(path)
        text = self._cleaner.tokenize_sentence(text)
        embeddings = self._embedder.sentence_embedding(text)
        return embeddings


import mysql.connector
import discord
import time
import re
import os
from discord.ext import commands
from functions import wantcardsuser, cardnamechecker, cardnamecheckername

class want(commands.Cog):

    def __init__(self,client):
        self.client = client

    #commands
    @commands.command(brief='Will @ People who have the card and how many')
    async def want(self, ctx, *, card):
        await ctx.send(f'looking up the users who have {card}......')
        if "}" in str(f'{card}') or "{" in str(f'{card}'):
            await ctx.send('Hey now. You stop that!')
        elif "None" in str(await cardnamechecker(f'{card}')):
            await ctx.send('The card name is incorrect')
        elif "None" in str(await wantcardsuser(f'{card}')):
            await ctx.send('No one has the card')
        else:
            from database import db_info
            db = mysql.connector.connect(**db_info)
            mycursor = db.cursor()
            atcard = ""
            noatcard = ""
            guild = str(ctx.guild.id)
            cardoutputname = await cardnamecheckername(f'{card}')
            mycursor.execute(
                f'SELECT i.discordid AS usid, SUM(i.count) AS count, i.name AS magicname FROM inventory i JOIN discorduser d ON i.discordid = d.discordid LEFT JOIN discordserver s ON i.discordid = s.discordid Where i.name = "{cardoutputname}" AND serverid = {guild} AND active = 1 AND at = 1 GROUP BY i.discordid')
            rows = mycursor.fetchall()
            for (usid, count, magicname) in rows:
                atcard += ("<@!{}> has {} {}\n".format(usid, count, magicname))
            mycursor.execute(
                f'SELECT d.name AS uname, SUM(i.count) AS count, i.name AS magicname FROM inventory i JOIN discorduser d ON i.discordid = d.discordid LEFT JOIN discordserver s ON i.discordid = s.discordid Where i.name = "{cardoutputname}" AND serverid = {guild} AND active = 1 AND at = 0 GROUP BY i.discordid')
            rows = mycursor.fetchall()
            for (uname, count, magicname) in rows:
                noatcard += ("{} has {} {}\n".format(uname, count, magicname))
            await ctx.send(
                f'<@!{ctx.author.id}> here are the users who have the card {card}:\n\n{atcard + noatcard}')
        mycursor.close()
        db.close()

    @commands.command(brief='Wll look up a mass import of who has the cards. ')
    async def masswant(self, ctx, *, card):
        cardsplit = (re.split("\n+", card))
        timeofsend = int(time.time())
        nonumber = ""
        lessthan10 = ""
        greaterthan10 = ""
        numbercheck = list(range(10))
        cardwantedlist = []
        if "}" in str(f'{card}') or "{" in str(f'{card}'):
            await ctx.send('Please remove { or } from your list!')
        else:
            await ctx.send('looking up the users who have cards from the list......')
            for card in cardsplit:
                if card[0] not in str(numbercheck):
                    nonumber += ('i.name = "{}" OR '.format(card))
                    cardwantedlist.append('{}'.format(card))
                elif card[0] == " ":
                    nonumber += ('i.name = "{}" OR '.format(card))
                    cardwantedlist.append('{}'.format(card))
                elif int(card[0] + card[1]) < 10:
                    lessthan10 += ('i.name = "{}" OR '.format(card[2:]))
                    cardwantedlist.append('{}'.format(card[2:]))
                else:
                    greaterthan10 += ('i.name = "{}" OR '.format(card[3:]))
                    cardwantedlist.append('{}'.format(card[3:]))
                whereintoquery = (nonumber + greaterthan10 + lessthan10)[:-3]
                from database import db_info
                db = mysql.connector.connect(**db_info)
                mycursor = db.cursor()
                atcard = ""
                noatcard = ""
                currentuser = ""
                userlist = []
                cardlist = []
                guild = str(ctx.guild.id)
                mycursor.execute(
                    f'SELECT i.discordid AS usid, SUM(i.count) AS count, i.name AS magicname FROM inventory i JOIN discorduser d ON i.discordid = d.discordid LEFT JOIN discordserver s ON i.discordid = s.discordid WHERE ({whereintoquery}) AND serverid = {guild} AND active = 1 AND at = 1 GROUP BY i.discordid, i.name ORDER BY i.name')
                rows = mycursor.fetchall()
                for (usid, count, magicname) in rows:
                    if currentuser == "" or currentuser != usid:
                        currentuser = usid
                        userlist.append(currentuser)
                userlist = list(set(userlist))
                for user in userlist:
                    atcard += "<@!{}> ".format(user)
                mycursor.execute(
                    f'SELECT d.name AS uname, SUM(i.count) AS count, i.name AS magicname FROM inventory i JOIN discorduser d ON i.discordid = d.discordid LEFT JOIN discordserver s ON i.discordid = s.discordid WHERE ({whereintoquery}) AND serverid = {guild} AND active = 1 GROUP BY i.discordid, i.name ORDER BY i.name')
                rows = mycursor.fetchall()
                currentcard = ""
                for (uname, count, magicname) in rows:
                    if currentcard == "" or currentcard != magicname:
                        currentcard = magicname
                        cardlist.append(magicname)
                        noatcard += "\n{}: \n".format(currentcard)
                    noatcard += ("{} has {} {}\n".format(uname, count, magicname))
                cardlist = list(set(cardlist))
                cardlist_lower = [card.lower() for card in cardlist]
                cardwantedlist_lower = [card.lower() for card in cardwantedlist]
                cardsnonehas = list(set(cardwantedlist_lower).difference(cardlist_lower))
                cardsnonehasmessege = ""
                for card in cardsnonehas:
                    cardsnonehasmessege += ('\n{}:\nNo one has this card or the card name was missed spelled\n'.format(card))
                filename = f'{timeofsend}{ctx.author.id}.txt'
                savepath = 'F:/Documents/Python Projects/MagicBot/Massexports'
                filepath = os.path.join(savepath, filename)
                with open(filepath, "w") as f:
                    f.write(F'{noatcard}\n{60 * "-"}\n{cardsnonehasmessege}')
                file = discord.File(filepath)
                flushdir(savepath)
        await ctx.send(file=file,
                       content=f'<@!{ctx.author.id}> we have found your cards!\n\nHere are users for quick whisper: {atcard}\n\nHere is the users who have cards on your list:')
        mycursor.close()

##removes files that are a minute old to keel the massexports folder from filling up
def flushdir(dir):
    now = time.time()
    for f in os.listdir(dir):
        fullpath = os.path.join(dir, f)
        if os.stat(fullpath).st_mtime < (now - 60):
            if os.path.isfile(fullpath):
                os.remove(fullpath)
            elif os.path.isdir(fullpath):
                flushdir(fullpath)

async def setup(client):
    await client.add_cog(want(client))


import pandas as pd
from datetime import datetime as dt
import os

df = pd.DataFrame({"my_date": [dt(2022, 1, 1, 0, 0, 0), dt.now()]})

df.info()

write_to_model(df)

model_name = context.current_model.name
df = ref(model_name)
output = f"my_date: {df['my_date'][0]}"
temp_dir = os.environ["temp_dir"]
with open(os.path.join(temp_dir, model_name + ".txt"), "w") as file:
    file.write(output)


"""Some common spatial plotting routines. Useful for contextualizing nanoARPES data."""
from typing import Any, Dict, List, Optional
import itertools

import numpy as np
import xarray as xr

import matplotlib.pyplot as plt
import matplotlib.patches as patches
from matplotlib import cm
import matplotlib.patheffects as path_effects
import matplotlib.gridspec as gridspec

from arpes.io import load_data
from arpes.plotting.annotations import annotate_point
from arpes.plotting.utils import (
    path_for_plot,
    frame_with,
    remove_colorbars,
    fancy_labels,
    ddata_daxis_units,
)
from arpes.provenance import save_plot_provenance
from arpes.typing import DataType
from arpes.utilities import normalize_to_spectrum
from arpes.utilities.xarray import unwrap_xarray_item

__all__ = ("reference_scan_spatial", "plot_spatial_reference")

@save_plot_provenance
def plot_spatial_reference(
    reference_map: DataType,
    data_list: List[DataType],
    offset_list: Optional[List[Dict[str, Any]]] = None,
    annotation_list: Optional[List[str]] = None,
    out: Optional[str] = None,
    plot_refs: bool = True,
):
    """Helpfully plots data against a reference scanning dataset.

    This is essential to understand
    where data was taken and can be used early in the analysis phase in order to highlight the
    location of your datasets against core levels, etc.

    Args:
        reference_map: A scanning photoemission like dataset
        data_list: A list of datasets you want to plot the relative locations of
        offset_list: Optionally, offsets given as coordinate dicts
        annotation_list: Optionally, text annotations for the data
        out: Where to save the figure if we are outputting to disk
        plot_refs: Whether to plot reference figures for each of the pieces of data in `data_list`
    """
    if offset_list is None:
        offset_list = [None] * len(data_list)

    if annotation_list is None:
        annotation_list = [str(i + 1) for i in range(len(data_list))]

    normalize_to_spectrum(reference_map)

    n_references = len(data_list)
    if n_references == 1 and plot_refs:
        fig, axes = plt.subplots(1, 2, figsize=(12, 5))
        ax = axes[0]
        ax_refs = [axes[1]]
    elif plot_refs:
        n_extra_axes = 1 + (n_references // 4)
        fig = plt.figure(figsize=(6 * (1 + n_extra_axes), 5))
        spec = gridspec.GridSpec(ncols=2 * (1 + n_extra_axes), nrows=2, figure=fig)
        ax = fig.add_subplot(spec[:2, :2])

        ax_refs = [
            fig.add_subplot(spec[i // (2 * n_extra_axes), 2 + i % (2 * n_extra_axes)])
            for i in range(n_references)
        ]
    else:
        ax_refs = []
        fig, ax = plt.subplots(1, 1, figsize=(6, 5))

    try:
        reference_map = reference_map.S.spectra[0]
    except Exception:
        pass

    reference_map = reference_map.S.mean_other(["x", "y", "z"])

    ref_dims = reference_map.dims[::-1]

    assert len(reference_map.dims) == 2
    reference_map.S.plot(ax=ax, cmap="Blues")

    cmap = cm.get_cmap("Reds")
    rendered_annotations = []
    for i, (data, offset, annotation) in enumerate(zip(data_list, offset_list, annotation_list)):
        if offset is None:
            try:
                offset = data.S.logical_offsets - reference_map.S.logical_offsets
            except ValueError:
                offset = {}

        coords = {c: unwrap_xarray_item(data.coords[c]) for c in ref_dims}
        n_array_coords = len(
            [cv for cv in coords.values() if isinstance(cv, (np.ndarray, xr.DataArray))]
        )
        color = cmap(0.4 + (0.5 * i / len(data_list)))
        x = coords[ref_dims[0]] + offset.get(ref_dims[0], 0)
        y = coords[ref_dims[1]] + offset.get(ref_dims[1], 0)
        ref_x, ref_y = x, y
        off_x, off_y = 0, 0
        scale = 0.03

        if n_array_coords == 0:
            off_y = 1
            ax.scatter([x], [y], s=60, color=color)
        if n_array_coords == 1:
            if isinstance(x, (np.ndarray, xr.DataArray)):
                y = [y] * len(x)
                ref_x = np.min(x)
                off_x = -1
            else:
                x = [x] * len(y)
                ref_y = np.max(y)
                off_y = 1

            ax.plot(x, y, color=color, linewidth=3)
        if n_array_coords == 2:
            off_y = 1
            min_x, max_x = np.min(x), np.max(x)
            min_y, max_y = np.min(y), np.max(y)
            ref_x, ref_y = min_x, max_y

            color = cmap(0.4 + (0.5 * i / len(data_list)), alpha=0.5)
            rect = patches.Rectangle((min_x, min_y), max_x - min_x, max_y - min_y, facecolor=color)
            color = cmap(0.4 + (0.5 * i / len(data_list)))

            ax.add_patch(rect)

        dp = ddata_daxis_units(ax)
        text_location = (
            np.asarray(
                [
                    ref_x,
                    ref_y,
                ]
            )
            + dp * scale * np.asarray([off_x, off_y])
        )
        text = ax.annotate(annotation, text_location, color="black", size=15)
        rendered_annotations.append(text)
        text.set_path_effects(
            [path_effects.Stroke(linewidth=2, foreground="white"), path_effects.Normal()]
        )
        if plot_refs:
            ax_ref = ax_refs[i]
            keep_preference = list(ref_dims) + [
                "eV",
                "temperature",
                "kz",
                "hv",
                "kp",
                "kx",
                "ky",
                "phi",
                "theta",
                "beta",
                "pixel",
            ]
            keep = [d for d in keep_preference if d in data.dims][:2]
            data.S.mean_other(keep).S.plot(ax=ax_ref)
            ax_ref.set_title(annotation)
            fancy_labels(ax_ref)
            frame_with(ax_ref, color=color, linewidth=3)

    ax.set_title("")
    remove_colorbars()
    fancy_labels(ax)
    plt.tight_layout()

    try:
        from adjustText import adjust_text

        adjust_text(
            rendered_annotations,
            ax=ax,
            avoid_points=False,
            avoid_objects=False,
            avoid_self=False,
            autoalign="xy",
        )
    except ImportError:
        pass

    if out is not None:
        plt.savefig(path_for_plot(out), dpi=400)
        return path_for_plot(out)

    return fig, [ax] + ax_refs

@save_plot_provenance
def reference_scan_spatial(data, out=None, **kwargs):
    """Plots the spatial content of a dataset, useful as a quick reference."""
    data = normalize_to_spectrum(data)

    dims = [d for d in data.dims if d in {"cycle", "phi", "eV"}]

    summed_data = data.sum(dims, keep_attrs=True)

    fig, ax = plt.subplots(3, 2, figsize=(15, 15))
    flat_axes = list(itertools.chain(*ax))

    summed_data.plot(ax=flat_axes[0])
    flat_axes[0].set_title(r"Full \textbf{eV} range")

    dims_except_eV = [d for d in dims if d != "eV"]
    summed_data = data.sum(dims_except_eV)

    mul = 0.2
    rng = data.coords["eV"].max().item() - data.coords["eV"].min().item()
    offset = data.coords["eV"].max().item()
    if offset > 0:
        offset = 0

    if rng > 3:
        mul = rng / 5.0

    for i in range(5):
        low_e, high_e = -mul * (i + 1) + offset, -mul * i + offset
        title = r"\textbf{eV}" + ": {:.2g} to {:.2g}".format(low_e, high_e)
        summed_data.sel(eV=slice(low_e, high_e)).sum("eV").plot(ax=flat_axes[i + 1])
        flat_axes[i + 1].set_title(title)

    y_range = flat_axes[0].get_ylim()
    x_range = flat_axes[0].get_xlim()
    delta_one_percent = ((x_range[1] - x_range[0]) / 100, (y_range[1] - y_range[0]) / 100)

    smart_delta = (2 * delta_one_percent[0], -1.5 * delta_one_percent[0])

    referenced = data.S.referenced_scans

    # idea here is to collect points by those that are close together, then
    # only plot one annotation
    condensed = []
    cutoff = 3  # 3 percent
    for index, _ in referenced.iterrows():
        ff = load_data(index)

        x, y, _ = ff.S.sample_pos
        found = False
        for cx, cy, cl in condensed:
            if abs(cx - x) < cutoff * abs(delta_one_percent[0]) and abs(cy - y) < cutoff * abs(
                delta_one_percent[1]
            ):
                cl.append(index)
                found = True
                break

        if not found:
            condensed.append((x, y, [index]))

    for fax in flat_axes:
        for cx, cy, cl in condensed:
            annotate_point(
                fax,
                (
                    cx,
                    cy,
                ),
                ",".join([str(l) for l in cl]),
                delta=smart_delta,
                fontsize="large",
            )

    plt.tight_layout()

    if out is not None:
        plt.savefig(path_for_plot(out), dpi=400)
        return path_for_plot(out)

    return fig, ax


import bpy
from . c_utils import executeSubtract_A_B
from ... base_types import AnimationNode, VectorizedSocket
from ... data_structures import VirtualDoubleList, DoubleList

class DelayTimeNode(AnimationNode, bpy.types.Node):
    bl_idname = "an_DelayTimeNode"
    bl_label = "Delay Time"
    dynamicLabelType = "HIDDEN_ONLY"

    useListA: VectorizedSocket.newProperty()
    useListB: VectorizedSocket.newProperty()

    def create(self):
        self.newInput(VectorizedSocket("Float", "useListA",
            ("Time", "time"), ("Times", "times")))
        self.newInput(VectorizedSocket("Float", "useListB",
            ("Delay", "delay", dict(value = 10)),
            ("Delays", "delays")))
        self.newOutput(VectorizedSocket("Float",
            ["useListA", "useListB"],
            ("Time", "outTime"), ("Times", "outTimes")))

    def drawLabel(self):
        if self.useListB: return "Delay Time"
        delaySocket = self.inputs["Delay"]
        if delaySocket.isUnlinked:
            value = delaySocket.value
            if value == int(value): return "Delay " + str(int(value)) + " Frames"
            else: return "Delay " + str(round(value, 2)) + " Frames"
        else: return "Delay Time"

    def getExecutionCode(self, required):
        if self.useListA or self.useListB:
            args = ", ".join(socket.identifier for socket in self.inputs)
            return "outTimes = self.executeList({})".format(args)
        else:
            return "outTime = time - delay"

    def executeList(self, time, delay):
        virtualTimes, virtualDelays = VirtualDoubleList.createMultiple((time, 0), (delay, 0))
        amount = VirtualDoubleList.getMaxRealLength(virtualTimes, virtualDelays)

        return executeSubtract_A_B(virtualTimes, virtualDelays, amount)


import os
from setuptools import setup

def read(filename: str):
    return open(os.path.join(os.path.dirname(__file__), filename)).read()

setup(
    name="hsolver",
    version="0.3",
    author="Boris Bantysh",
    author_email="bbantysh60000@gmail.com",
    description="The tool for solving quantum state evolution under periodic hamiltonian",
    license="GPL-3.0",
    keywords="periodic hamiltonian",
    url="https://github.com/bbantysh/hsolver",
    packages=["hsolver"],
    long_description=read("README.md"),
    install_requires=["numpy", "scipy", "pytest"]
)


#!/usr/bin python3
# -*- encoding: utf-8 -*-
# @Author : cobra
# @File : preprocess.py
# @Time : 2020/9/20 23:06
import pandas as pd
import jieba
import keras
import json
from keras import backend as K

from sklearn.preprocessing import LabelEncoder
from model.text_cnn import simple_text_cnn
from sklearn.model_selection import train_test_split

from keras.preprocessing.text import Tokenizer

from keras.preprocessing.sequence import pad_sequences

def convert_json2excel(infile, outfile):
    """
    转换json格式为excel
    :param infile:
    :param outfile:
    :return:
    """
    f = open(infile, encoding='utf-8')
    df_out = pd.DataFrame()
    label_id_list = []
    label_list = []
    text_list = []
    keyword_list = []

    for line in f.readlines():
        line = line.strip()
        line = json.loads(line)
        label_id_list.append(line['label'])
        label_list.append(line['label_desc'])
        text_list.append(line['sentence'])
        keyword_list.append(line['keywords'])
    df_out['label_id'] = label_id_list
    df_out['label'] = label_list
    df_out['text'] = text_list
    df_out['keywords'] = keyword_list
    df_out.to_excel(outfile)

def cut_x(x):

    return list(jieba.cut(x)) # jieba.cut(x)返回值是一个generator，所以前面要加list

def excel_preprocess(infile):
    df = pd.read_excel(infile)
    function_cut = lambda x: list(jieba.cut(x))
    df['words'] = df['text'].apply(cut_x)
    return df

def train_test_split_dataset(text,label,test_size = 0.1):
    return train_test_split(text,label,test_size = 0.1)

def get_token_id(text_list):
    tokenizer = Tokenizer()
    tokenizer.fit_on_texts(text_list)
    vocab = tokenizer.word_index
    return tokenizer

def pad_sequence(text,max_len =50,padding='post'):
    text_pad = pad_sequences(text,maxlen=50,padding=padding)
    return text_pad

def self_loss(y_true, y_pred):
    return K.sum((y_pred + y_true), axis=-1)

if __name__ == '__main__':
    # convert_json2excel('../data/train.json', '../data/train.xlsx')

    df = excel_preprocess('../data/train_demo.xlsx')
    tokenizer= get_token_id(list(df['words']))
    x_train, x_test, y_train, y_test = train_test_split(list(df['words']), list(df['label']), test_size=0.1)
    x_train = tokenizer.texts_to_sequences(x_train)
    x_test = tokenizer.texts_to_sequences(x_test)
    x_train_pad = pad_sequence(x_train,max_len =50)
    x_test_pad = pad_sequence(x_test, max_len=50)
    encoder = LabelEncoder()
    y_train_id = encoder.fit_transform(y_train)
    model = simple_text_cnn((50,),len(tokenizer.word_index))
    model.summary()
    model.compile(loss=self_loss, optimizer='adam', metrics=['accuracy'])
    one_hot_labels = keras.utils.to_categorical(y_train_id, num_classes=15)  # 将标签转换为one-hot编码
    model.fit(x_train_pad, one_hot_labels, batch_size=128, epochs=10)