ajaj.py 14.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
#!/usr/bin/env python
# -*- encoding: utf-8 -*-

"""Les "pages" qui sont destinées à répondre aux requêtes AJAJ."""

import json

# L'objet de réponse HTTP
from django.http import HttpResponse

# Les formulaires
import forms
# Les utilitaires
import utilities
# La communication avec le backend
import nk

# Pour bypasser le test de Cross-Site Request Forgery
from django.views.decorators.csrf import csrf_exempt

21
# TODO: vérifier que les exempts suivants peuvent être retirés sans risques
22
@csrf_exempt
23
def quick_search(request, mode="basic"):
24 25 26 27 28 29 30 31 32 33 34 35
    """Renvoie l'objet JSON résultat d'un quick_search,
       destiné à être chargé par javascript"""
    if (request.method == "GET") or (request.session.get("logged", None) != "ok"):
        return HttpResponse("Get the fuck out of here", status=444)
    else:
        try:
            asked = request.POST["asked"]
        except:
            return HttpResponse("")
        success, sock_ou_response = nk.socket_still_alive(request)
        if success:
            sock = sock_ou_response
36
            data = [asked, "x"] if mode == "dons" else [asked]
37 38 39 40 41
            sock.write(json.dumps(["quick_search", data]))
            out = nk.full_read(sock)["msg"]
            return HttpResponse(json.dumps(out))
        else:
            response = sock_ou_response
42
            return HttpResponse(u'"Erreur"')
43

44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
@csrf_exempt
def search_pot(request, idpot = None):
    """Renvoie l'objet JSON résultat d'une recherche pour les entrées d'un [Pot],
       destiné à être chargé par javascript"""
    if (request.method == "GET") or (request.session.get("logged", None) != "ok"):
        return HttpResponse("Get the fuck out of here", status=444)
    else:
        try:
            asked = request.POST["asked"]
            idpot = int(idpot)
        except:
            return HttpResponse("")
        success, sock_ou_response = nk.socket_still_alive(request)
        if success:
            sock = sock_ou_response
            data = [asked, idpot]
            sock.write(json.dumps(["search_pot", data]))
            out = nk.full_read(sock)["msg"]
            return HttpResponse(json.dumps(out))
        else:
            response = sock_ou_response
            return HttpResponse(u'"Erreur"')


68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
@csrf_exempt
def get_display_info(request):
    """Renvoie l'objet JSON résultat d'un get_display_info
       destiné à être chargé par javascript"""
    if (request.method == "GET") or (request.session.get("logged", None) != "ok"):
        return HttpResponse("Get the fuck out of here", status=444)
    else:
        try:
            asked = json.loads(request.POST["asked"])
        except:
            return HttpResponse("")
        success, sock_ou_response = nk.socket_still_alive(request)
        if success:
            sock = sock_ou_response
            data = asked
            sock.write(json.dumps(["get_display_info", data]))
            out = nk.full_read(sock)["msg"]
            return HttpResponse(json.dumps(out))
        else:
87
            HttpResponse(u'"Erreur"')
88

89 90 91 92 93 94 95 96 97 98 99 100 101 102
@csrf_exempt
def search(request):
    """Renvoie l'objet JSON résultat d'un search,
       destiné à être chargé par javascript"""
    if (request.method == "GET") or (request.session.get("logged", None) != "ok"):
        return HttpResponse("Get the fuck out of here", status=444)
    else:
        try:
            asked = request.POST["asked"]
        except:
            return HttpResponse("")
        success, sock_ou_response = nk.socket_still_alive(request)
        if success:
            sock = sock_ou_response
103 104 105 106
            # case-insensitive, inclure les comptes non à jour d'adhésion,
            # afficher les alias, rechercher sur les alias,
            # afficher les anciens pseudos, rechercher sur les anciens pseudos
            flags = "ioaAhH"
107 108 109 110 111 112 113 114
            data = [flags, ["idbde", "nom", "prenom", "pseudo", "mail"], asked]
            sock.write(json.dumps(["search", data]))
            out = nk.full_read(sock)["msg"]
            return HttpResponse(json.dumps(out))
        else:
            response = sock_ou_response
            return response

115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139

@csrf_exempt
def search_readhesion(request):
    """Renvoie l'objet JSON résultat d'un search,
       destiné à être chargé par javascript"""
    if (request.method == "GET") or (request.session.get("logged", None) != "ok"):
        return HttpResponse("Get the fuck out of here", status=444)
    else:
        try:
            asked = request.POST["asked"]
        except:
            return HttpResponse("")
        success, sock_ou_response = nk.socket_still_alive(request)
        if success:
            sock = sock_ou_response
            flags = "ioaAhH" # dans la recherche de base on ne cherhe pas sur les alias et les historiques, mais on prend les comptes non à jour
            data = [flags, ["idbde", "nom", "prenom", "pseudo", "mail"], asked]
            sock.write(json.dumps(["search", data]))
            out = nk.full_read(sock)["msg"]
            return HttpResponse(json.dumps(out))
        else:
            response = sock_ou_response
            return response


140 141
@csrf_exempt
def do_entree_pot(request):
142
    """Effectue l'entrée d'une personne dans un pot dans la BDD"""
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
    if (request.method == "GET") or (request.session.get("logged", None) != "ok"):
        return HttpResponse("Get the fuck out of here", status=444)
    else:
        try:
            entree = request.POST["entree"]
            entree = json.loads(entree)
        except:
            return HttpResponse(entree)
        success, sock_ou_response = nk.socket_still_alive(request)
        if success:
            sock = sock_ou_response
            sock.write(json.dumps(["do_entree_pot", entree]))
            out = nk.full_read(sock)["msg"]
            return HttpResponse(json.dumps(out))
        else:
            response = sock_ou_response
            return response



163
@csrf_exempt
164
def get_boutons(request, flags=""):
165 166 167 168 169 170
    """Renvoie l'objet JSON résultat d'un get_boutons,
       destiné à être chargé par javascript"""
    if (request.method == "GET") or (request.session.get("logged", None) != "ok"):
        return HttpResponse("Get the fuck out of here", status=444)
    else:
        try:
171 172
            asked = request.POST.get("asked", "")
            categorie = request.POST.get("categorie", "")
173
        except:
174
            return HttpResponse("HTTP/1.1 Bad Request", status=400)
175 176 177
        success, sock_ou_response = nk.socket_still_alive(request)
        if success:
            sock = sock_ou_response
178
            data = [asked, categorie, flags]
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
            sock.write(json.dumps(["get_boutons", data]))
            out = nk.full_read(sock)["msg"]
            return HttpResponse(json.dumps(out))
        else:
            response = sock_ou_response
            return response

@csrf_exempt
def do_conso(request):
    """Effectue les consos envoyées en POST par javascript"""
    if (request.method == "GET") or (request.session.get("logged", None) != "ok"):
        return HttpResponse("Get the fuck out of here", status=444)
    else:
        try:
            consodata = request.POST["consodata"]
            consodata = [[int(i) for i in triplet.split(",")] for triplet in consodata[1:-1].split("),(")]
        except:
Vincent Le gallic's avatar
Vincent Le gallic committed
196
            return HttpResponse(u'"Bad request"', status=400)
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
        success, sock_ou_response = nk.socket_still_alive(request)
        if success:
            sock = sock_ou_response
            sock.write(json.dumps(["consos", consodata]))
            out = nk.full_read(sock)
            return HttpResponse(json.dumps(out))
        else:
            return HttpResponse(u'"Erreur"')

@csrf_exempt
def get_photo(request, idbde=None):
    """Affiche dans une page HTML la photo demandée.
       Si elle n'existe pas encore (ou n'est pas à jour), la demande au serveur
       et la stocke dans un ficher."""
    try:
        idbde = int(idbde)
    except Exception as e:
Vincent Le gallic's avatar
Vincent Le gallic committed
214
        return HttpResponse("Bad Request", status=400)
215
    # On appelle alors la fonction standard
216
    success, sock_ou_response, variables_standard = utilities.get_varsock(request, socket=True)
217 218 219 220 221 222
    if success:
        sock = sock_ou_response
        utilities._provide_photo(sock, idbde)
        urlphoto = utilities._get_url_photo(idbde)
        return HttpResponse('<img src = "%s"></img>' % (urlphoto))
    else:
223
        return HttpResponse(u'"Erreur"')
224 225 226

@csrf_exempt
def do_credit_retrait(request, action):
Vincent Le gallic's avatar
Vincent Le gallic committed
227
    """Gestion de la requête AJAJ pour un crédit ou un retrait."""
228
    types = {"especes": "Espèces", "cheque": "Chèque", "virement": "Virement bancaire", "cb" : "Carte bancaire"}
229 230 231
    actions_write = {"credit": "crédit", "retrait": "retrait"}
    actions_socket = {"credit": "crediter", "retrait": "retirer"}
    # On appelle la fonction standard
232
    success, sock_ou_response, variables_standard = utilities.get_varsock(request, socket=True)
233 234 235 236
    if success:
        sock = sock_ou_response
        # on n'a pas besoin du prefix parce que le JS a filé les paramètre sans.
        form = forms.CreditRetraitForm(request.POST, label_suffix=" :")
237 238 239 240 241 242
        try:
            ok = form.is_valid()
        except forms.CreditRetraitWithoutIdbde:
            errmsg = u"Il faut penser à cliquer sur un compte avant de créditer/retirer."
            return HttpResponse(errmsg)
        if ok:
243
            data = form.cleaned_data
244
            if (data["type"] in ["cheque", "virement"] and "" in [data["nom"], data["prenom"], data["banque"]]):
245
                return HttpResponse("""Pour un %s par %s, les champs Nom, Prénom et Banque doivent être spécifiés.""" % (actions_write[action], types[data["type"]]))
246 247
            if (data["type"] in ["cb"] and "" in [data["nom"], data["prenom"]]):
                return HttpResponse("""Pour un %s par %s, les champs Nom et Prénom doivent être spécifiés.""" % (actions_write[action], types[data["type"]]))
248 249 250 251 252 253 254 255 256 257 258 259
            to_send = [data["idbde"], data["montant"], data["type"],
                       {"nom": data["nom"], "prenom": data["prenom"], "banque": data["banque"], "commentaire" : data["commentaire"]}]
            paquet = [actions_socket[action], to_send]
            sock.write(json.dumps(paquet))
            out = nk.full_read(sock)
            return HttpResponse(json.dumps(out))
        else:
            errmsg = "Ce %s est invalide :\n" % (actions_write[action])
            for (k,v) in form.errors.items():
                errmsg += "%s : %s\n" % (k,"".join([str(i) for i in v]))
            return HttpResponse(errmsg)
    else:
260
        return HttpResponse(u'"Erreur"')
261

Maxime Bombar's avatar
Maxime Bombar committed
262
@csrf_exempt
263
def do_transfert(request):
Vincent Le gallic's avatar
Vincent Le gallic committed
264
    """Gestion de la requête AJAJ pour un transfert."""
265

266
    # On appelle la fonction standard
267
    success, sock_ou_response, variables_standard = utilities.get_varsock(request, socket=True)
268 269 270 271 272 273 274 275 276
    if success:
        sock = sock_ou_response
        if request.method != "POST" or not request.POST.has_key("transfertdata"):
            return HttpResponse("Bad request", status=400)
        transfertdata = request.POST["transfertdata"]
        try:
            transfertdata = json.loads(transfertdata)
        except ValueError:
            return HttpResponse("Failed to decode JSON object.", status=500)
277 278 279 280 281 282
        if not( isinstance(transfertdata, list) and
                [type(i) for i in transfertdata] == [bool, list, list, unicode, unicode]):
            return HttpResponse("Bad parameter %r" % [type(i) for i in transfertdata], status=500)
        is_don, emetteurs, destinataires, montant, commentaire = transfertdata

        # Formattage des champs
283 284 285 286 287 288 289 290
        try:
            montant = float(montant)
        except ValueError:
            return HttpResponse(json.dumps({"retcode" : 1111, "msg" : None, "errmsg" : """Transfert impossible : "%s" n'est pas un montant valide.""" % (montant,)}))
        if emetteurs == []:
            return HttpResponse(json.dumps({"retcode" : 1112, "msg" : None, "errmsg" : "Transfert impossible : pas d'émetteurs."}))
        if destinataires == []:
            return HttpResponse(json.dumps({"retcode" : 1113, "msg" : None, "errmsg" : "Transfert impossible : pas de destinataires."}))
291
        montant = int(round(montant * 100))
292 293 294 295 296 297 298 299 300 301

        # Sanity check: si don, alors emetteurs devrait être
        if is_don and set(emetteurs) != {request.session["whoami"]["idbde"]}:
            return HttpResponse("emetteurs invalide pour dons", status=403)

        # Forgeons le paquet à envoyer
        if is_don:
            paquet = ["dons", [destinataires, montant, commentaire]]
        else:
            paquet = ["transferts", [emetteurs, destinataires, montant, commentaire]]
302

303
        # Et on envoie le tout
304 305 306 307
        sock.write(json.dumps(paquet))
        out = nk.full_read(sock)
        return HttpResponse(json.dumps(out))
    else:
308
        return HttpResponse(u'"Erreur"')
309 310 311 312 313 314 315 316 317 318 319 320
""""""
@csrf_exempt
def toggle_transaction(request):
    """Gestion de la requête AJAJ pour la (dé)validation d'une transaction.

       Reçoit en POST une chaîne "idtransaction,devalider" où
        * ``idtransaction`` : id de la transaction à toggle (str)
        * ``devalider`` = ``"true"`` si on veut dévalider, ``"false"`` sinon.
        """

    if (request.method == "GET") or (request.session.get("logged", None) != "ok"):
        return HttpResponse("Get the fuck out of here", status=444)
321

322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338
    else:
        try:
            data = request.POST["data"].split(",")
            idtransaction, devalidate = int(data[0]), (data[1] == "true")

        except:
            return HttpResponse(u'"Bad request"', status=400)
        success, sock_ou_response = nk.socket_still_alive(request)
        if success:
            sock = sock_ou_response
            variables = {}
            cmd = "%svalider_transaction" % ("de" if devalidate else "")
            sock.write(json.dumps([cmd, idtransaction]))
            out = nk.full_read(sock)
            return HttpResponse(json.dumps(out))
        else:
            return HttpResponse(u'"Erreur"')
339 340 341

def stats_pot(request, idpot = None):
    if (request.method == "GET") or (request.session.get("logged", None) != "ok"):
Praibait's avatar
Praibait committed
342
        return HttpResponse("Get the fuck out of here", status=444)
343 344 345 346 347 348
    else:
        success, sock_ou_response = nk.socket_still_alive(request)
        if success:
            sock = sock_ou_response
            sock.write(json.dumps(["stats_entree_pot", idpot]))
            out = nk.full_read(sock)["msg"]
Praibait's avatar
Praibait committed
349 350 351 352 353
            if out:
                out = [ [l[0], l[1]] for l in out]
                return HttpResponse(json.dumps(out))
            else:
                return HttpResponse(u'"Bad request"', status=400)
354 355
        else:
            return HttpResponse(u'"Erreur"')