From 8bec0dac79e750d0040de8a009c6ae864479642e Mon Sep 17 00:00:00 2001 From: Greg Burri Date: Thu, 15 May 2008 21:19:21 +0000 Subject: [PATCH] ADD troll sur la page principale --- css/1/euphorik.css | 7 +- css/1/pageMinichat.css | 19 +- doc/TODO.txt | 5 +- doc/protocole3.txt | 2 +- js/pageAdmin.js | 9 +- js/pageMinichat.js | 45 +++-- modules/erl/euphorik_bd.erl | 118 +++++++++---- modules/erl/euphorik_deamon.erl | 22 +++ .../erl/euphorik_minichat_conversation.erl | 67 +++----- modules/erl/euphorik_protocole.erl | 162 +++++++++++------- 10 files changed, 300 insertions(+), 156 deletions(-) create mode 100755 modules/erl/euphorik_deamon.erl diff --git a/css/1/euphorik.css b/css/1/euphorik.css index c3a4ace..61a755f 100755 --- a/css/1/euphorik.css +++ b/css/1/euphorik.css @@ -14,7 +14,7 @@ body { font-family: sans-serif; font-size: 12px; color: #EEEEEE; - text-align: center; /* uniquement pour IE */ + /*text-align: center;*/ /* uniquement pour IE */ background-color: #DFDFDF; background-image: url(../../img/css1/fond.png) } @@ -34,7 +34,6 @@ body { left: 300px; font-size: 11px; background-color: #000000; - text-align: left; } #menu div { cursor: pointer; @@ -62,7 +61,6 @@ body { position: relative; font-size: 12px; background-color: #000000; - text-align : left; padding: 30px 10px 15px 10px; } @@ -124,7 +122,8 @@ body { border-style: none; } -div#info { +div#info { + text-align: center; width:100%; position: fixed; left: 0px; diff --git a/css/1/pageMinichat.css b/css/1/pageMinichat.css index a753ba5..f4e1e5a 100755 --- a/css/1/pageMinichat.css +++ b/css/1/pageMinichat.css @@ -1,6 +1,5 @@ #page.minichat { padding: 25px 0px 15px 0px; - text-align: center } #page.minichat img { @@ -46,12 +45,26 @@ margin-left: 1px } +#page.minichat #trollCourant { + border-top: 1px solid; + border-bottom: 1px solid; + border-color: #253f18; + background-color: #0c2003; + margin-top: 4px; + margin-bottom: 8px; + padding : 1px 0px 1px 10px +} + +#page.minichat #trollCourant .troll { + font-style: italic; + color: #FFFF88 +} + #page.minichat .titreSmiles:hover { background-color: #2d8800; } #page.minichat form { - text-align: left; margin-bottom: 15px; padding-left: 10px; } @@ -96,7 +109,6 @@ border-left-width: 5px; border-left-style: solid; border-color: transparent; - text-align: left; padding-right: 5px; padding-left: 4px; cursor: pointer; @@ -200,6 +212,7 @@ } #page.minichat #conversations .titre { + text-align: center; padding-right: 8px; background-color: #4b4215 } diff --git a/doc/TODO.txt b/doc/TODO.txt index da163ae..9cd64c8 100755 --- a/doc/TODO.txt +++ b/doc/TODO.txt @@ -2,7 +2,10 @@ === v1.0 === -* Est-ce que client.dernierMessageErreur est vraiment utile ?? +* Est-ce que client.dernierMessageErreur est vraiment utile ?? +* Problème des images dans les trolls +* Finir l'édition (mémoriser le contenu) des trolls +* marquer lors de l'affichage des login dans le chat pour les personnes n'en ayant pas [80%] Un statut "EK" avec plein de privilège à la con. (avoir une petite étoile à coté de son nick ou le nick d'une certaine couleur) * Une page "admin" avec : * Trolls : La liste des trolls proposés. L'admin peut éditer ses propres trolls. diff --git a/doc/protocole3.txt b/doc/protocole3.txt index 8c383c7..2646a4b 100644 --- a/doc/protocole3.txt +++ b/doc/protocole3.txt @@ -156,7 +156,7 @@ La premi L'ordre des conversation est le même que celui des données de l'utilisateur. Le format de la date n'est pas formel. { - "reply" : "new_messages", + "reply" : "new_message", "conversations" : [ { "last_page" : true | false, diff --git a/js/pageAdmin.js b/js/pageAdmin.js index 4c34f58..fd1ddd4 100644 --- a/js/pageAdmin.js +++ b/js/pageAdmin.js @@ -208,12 +208,14 @@ Trolls.prototype.rafraichirTrolls = function() { $("span", troll).css("display", "none") $(troll).append( - '

modifierannuler

' + '

modifierannuler

' ) var virerLeFormulaire = function() { $("form", troll).remove() - $("span", troll).css("display", "inline") + $('span', troll).css("display", "inline") } $("span.modifier", troll).click( function() @@ -234,7 +236,8 @@ Trolls.prototype.rafraichirTrolls = function() thisTrolls.dernierTroll = data["trolls"][data["trolls"].length - 1]["troll_id"] break case "troll_modified" : - $("#trolls #troll" + data["troll_id"] + " .content").html(data["content"]) + $("#trolls #troll" + data["troll_id"] + " .content").html(thisTrolls.formateur.traitementComplet(data["content"], $("#trolls #troll" + data["troll_id"] + " .author").html())) + $("#trolls #troll" + data["troll_id"] + " .contentPasFormat").html(data["content"]) break case "troll_deleted" : $("#trolls #troll"+data["troll_id"]).remove() diff --git a/js/pageMinichat.js b/js/pageMinichat.js index ed0321c..1f6a118 100755 --- a/js/pageMinichat.js +++ b/js/pageMinichat.js @@ -15,6 +15,7 @@ function PageMinichat(client, formateur, util) PageMinichat.prototype.contenu = function() { return '\ +
Troll de la semaine :
\
\

\ \ @@ -671,6 +672,8 @@ function Messages(client, formateur, util) this.conversations = new Array() // les conversations, la première représente la conversation principale this.nouvelleConversation(0) + this.trollIdCourant = 0 + this.pageEvent = new PageEvent("chat", this.util) } @@ -682,10 +685,11 @@ Messages.prototype.getJSONrafraichirMessages = function() var mess = { "message_count" : conf.nbMessageAffiche, "main_page" : this.client.pagePrincipale, - "conversations" : this.getJSONConversations() + "conversations" : this.getJSONConversations(), + "troll_id" : this.trollIdCourant } - if (this.client.cookie != null) mess["cookie"] = this.client.cookie; + if (this.client.cookie != null) mess["cookie"] = this.client.cookie mess["last_message_id"] = this.conversations[0].idDernierMessageAffiche return mess @@ -894,21 +898,32 @@ Messages.prototype.rafraichirMessages = function(vider) function() { return thisMessages.getJSONrafraichirMessages() }, function(data) { - if (vider) - { - thisMessages.viderMessages() - vider = false - } - - // ajoute les messages reçus à leur conversation respective - for (var numConv = 0; numConv < data["conversations"].length; numConv++) - { - if (! thisMessages.ajouterMessages(data["conversations"][numConv], numConv)) + if (vider) + { + thisMessages.viderMessages() + vider = false + } + + // en fonction du message + switch(data["reply"]) + { + case "new_troll" : + thisMessages.trollIdCourant = data["troll_id"] + $("#trollCourant .troll").html(thisMessages.formateur.traitementComplet(data["content"])) + break + + case "new_messages" : + // ajoute les messages reçus à leur conversation respective + for (var numConv = 0; numConv < data["conversations"].length; numConv++) { - thisMessages.util.messageDialogue("La conversation {" + thisMessages.client.conversations[numConv -1].root.toString(36) + "} n'existe pas") - thisMessages.client.supprimerConversation(numConv - 1) + if (! thisMessages.ajouterMessages(data["conversations"][numConv], numConv)) + { + thisMessages.util.messageDialogue("La conversation {" + thisMessages.client.conversations[numConv -1].root.toString(36) + "} n'existe pas") + thisMessages.client.supprimerConversation(numConv - 1) + } } - } + break + } } ) } diff --git a/modules/erl/euphorik_bd.erl b/modules/erl/euphorik_bd.erl index e10ef2a..d354c21 100755 --- a/modules/erl/euphorik_bd.erl +++ b/modules/erl/euphorik_bd.erl @@ -52,17 +52,22 @@ % trolls : trolls/0, trolls/1, + trolls_attente/1, put_troll/2, mod_troll/2, del_troll/1, troll_by_id/1, + current_troll/0, + elire_troll/0, % versions : update_version/1, % utiles : resultat_transaction/1 -]). +]). + +-import(qlc, [e/1, e/2, q/1, cursor/1]). -include("../include/euphorik_bd.hrl"). -include("../include/euphorik_defines.hrl"). @@ -239,7 +244,7 @@ update_pseudo_user(UserId, Pseudo) -> % Renvoie tous les users. users() -> resultat_transaction(mnesia:transaction(fun() -> - qlc:e(qlc:q([E || E <- mnesia:table(user)])) + e(q([E || E <- mnesia:table(user)])) end)). @@ -248,7 +253,7 @@ users() -> user_by_cookie(Cookie) -> resultat_transaction(mnesia:transaction( fun() -> - case qlc:e(qlc:q([E || E <- mnesia:table(user), E#user.cookie =:= Cookie])) of + case e(q([E || E <- mnesia:table(user), E#user.cookie =:= Cookie])) of [User] -> {ok, User}; _ -> erreur end @@ -259,7 +264,7 @@ user_by_cookie(Cookie) -> user_by_id(ID) -> resultat_transaction(mnesia:transaction( fun() -> - case qlc:e(qlc:q([E || E <- mnesia:table(user), E#user.id =:= ID])) of + case e(q([E || E <- mnesia:table(user), E#user.id =:= ID])) of [User] -> {ok, User}; _ -> erreur end @@ -270,7 +275,7 @@ user_by_id(ID) -> user_by_login(Login) -> resultat_transaction(mnesia:transaction( fun() -> - Users = qlc:e(qlc:q([E || E <- mnesia:table(user), E#user.login =:= Login])), + Users = e(q([E || E <- mnesia:table(user), E#user.login =:= Login])), case Users of [User] -> {ok, User}; _ -> erreur @@ -282,7 +287,7 @@ user_by_login(Login) -> toggle_ek_master(User_id) -> resultat_transaction(mnesia:transaction( fun() -> - Users = qlc:e(qlc:q([E || E <- mnesia:table(user), E#user.id =:= User_id])), + Users = e(q([E || E <- mnesia:table(user), E#user.id =:= User_id])), case Users of [User] -> mnesia:write(User#user{ek_master = not User#user.ek_master}); @@ -295,7 +300,7 @@ toggle_ek_master(User_id) -> user_by_login_password(Login, Password) -> resultat_transaction(mnesia:transaction( fun() -> - case qlc:e(qlc:q([E || E <- mnesia:table(user), E#user.login =:= Login, E#user.password =:= Password])) of + case e(q([E || E <- mnesia:table(user), E#user.login =:= Login, E#user.password =:= Password])) of [User | _] -> {ok, User}; _ -> erreur end @@ -307,7 +312,7 @@ user_by_login_password(Login, Password) -> user_by_mess(Id) -> resultat_transaction(mnesia:transaction( fun() -> - case qlc:e(qlc:q([U || U <- mnesia:table(user), M <- mnesia:table(minichat), M#minichat.id =:= Id, M#minichat.auteur_id =:= U#user.id])) of + case e(q([U || U <- mnesia:table(user), M <- mnesia:table(minichat), M#minichat.id =:= Id, M#minichat.auteur_id =:= U#user.id])) of [User | _] -> {ok, User}; _ -> erreur end @@ -320,9 +325,9 @@ user_by_mess(Id) -> nouveau_message(Mess, Auteur_id, Repond_A) -> % regarde si les id 'Repond_A' existent F = fun() -> - Nb_id_trouve = length(qlc:e(qlc:q([E#minichat.id || E <- mnesia:table(minichat), lists:member(E#minichat.id, Repond_A)]))), + Nb_id_trouve = length(e(q([E#minichat.id || E <- mnesia:table(minichat), lists:member(E#minichat.id, Repond_A)]))), % est-ce que l'auteur existe ? - Auteur = case qlc:e(qlc:q([E || E <- mnesia:table(user), E#user.id =:= Auteur_id])) of + Auteur = case e(q([E || E <- mnesia:table(user), E#user.id =:= Auteur_id])) of [A] -> A; _ -> throw("L'auteur du message est introuvable") end, @@ -380,7 +385,7 @@ messages(N) -> % Renvoie N messages se trouvant sur la page P messages(N, P) -> F = fun() -> - C = qlc:cursor(qlc:q([E || E <- qlc:keysort(2, mnesia:table(minichat), [{order, descending}])])), + C = cursor(q([E || E <- qlc:keysort(2, mnesia:table(minichat), [{order, descending}])])), if P > 1 -> qlc:next_answers(C, N * (P - 1)); true -> ok end, @@ -401,7 +406,7 @@ messages(Id, N, P) -> message_by_id(Id) -> case resultat_transaction(mnesia:transaction( fun() -> - qlc:e(qlc:q([E || E <- qlc:keysort(2, mnesia:table(minichat), [{order, ascending}]), Id =:= E#minichat.id])) + e(q([E || E <- qlc:keysort(2, mnesia:table(minichat), [{order, ascending}]), Id =:= E#minichat.id])) end )) of [M] -> {ok, M}; @@ -414,8 +419,8 @@ messages_by_ids(Ids) -> resultat_transaction(mnesia:transaction( fun() -> % TODO : optimisations ? serait-ce du O(n) ? - Query = qlc:q([E || E <- qlc:keysort(2, mnesia:table(minichat), [{order, ascending}]), lists:any(fun(Id) -> Id =:= E#minichat.id end, Ids)]), - qlc:e(Query) + Query = q([E || E <- qlc:keysort(2, mnesia:table(minichat), [{order, ascending}]), lists:any(fun(Id) -> Id =:= E#minichat.id end, Ids)]), + e(Query) end )). @@ -424,14 +429,14 @@ messages_by_ids(Ids) -> % TODO : ya pas plus simple ? message_existe(Id) -> resultat_transaction(mnesia:transaction(fun() -> - length(qlc:e(qlc:q([E#minichat.id || E <- mnesia:table(minichat), E#minichat.id =:= Id]))) =:= 1 + length(e(q([E#minichat.id || E <- mnesia:table(minichat), E#minichat.id =:= Id]))) =:= 1 end)). % Renvoie les reponses (utilisé normalement uniquement pendant le debug). reponses() -> F = fun() -> - qlc:e(qlc:q([E || E <- mnesia:table(reponse_minichat)])) + e(q([E || E <- mnesia:table(reponse_minichat)])) end, resultat_transaction(mnesia:transaction(F)). @@ -440,7 +445,7 @@ reponses() -> repond_a(M_id) -> resultat_transaction(mnesia:transaction( fun() -> - qlc:e(qlc:q( + e(q( [M || E <- mnesia:table(reponse_minichat), M <- mnesia:table(minichat), E#reponse_minichat.repondant =:= M_id, @@ -453,7 +458,7 @@ repond_a(M_id) -> est_une_reponse_a_user(Id_user, Id_mess) -> case mnesia:transaction( fun() -> - qlc:e(qlc:q([ + e(q([ M#minichat.auteur_id || M <- mnesia:table(minichat), R <- mnesia:table(reponse_minichat), M#minichat.auteur_id =:= Id_user, M#minichat.id =:= R#reponse_minichat.cible, R#reponse_minichat.repondant =:= Id_mess ]), [{unique_all, true}]) @@ -468,7 +473,7 @@ est_une_reponse_a_user(Id_user, Id_mess) -> a_repondu_a_message(Id_user, Id_mess) -> case mnesia:transaction( fun() -> - qlc:e(qlc:q([ + e(q([ M#minichat.auteur_id || M <- mnesia:table(minichat), R <- mnesia:table(reponse_minichat), R#reponse_minichat.cible =:= Id_mess, R#reponse_minichat.repondant =:= M#minichat.id, M#minichat.auteur_id =:= Id_user ]), [{unique_all, true}]) @@ -483,7 +488,7 @@ a_repondu_a_message(Id_user, Id_mess) -> possede_message(Id_user, Id_mess) -> case mnesia:transaction( fun() -> - qlc:e(qlc:q([E#minichat.auteur_id || E <- mnesia:table(minichat), E#minichat.id =:= Id_mess])) + e(q([E#minichat.auteur_id || E <- mnesia:table(minichat), E#minichat.id =:= Id_mess])) end ) of {atomic, [Id_user | []]} -> true; @@ -494,7 +499,7 @@ possede_message(Id_user, Id_mess) -> ip_table() -> resultat_transaction(mnesia:transaction( fun() -> - qlc:e(qlc:q([IP || IP <- mnesia:table(ip_table)])) + e(q([IP || IP <- mnesia:table(ip_table)])) end )). @@ -523,7 +528,7 @@ deban(IP) -> est_banni(User_id) -> resultat_transaction(mnesia:transaction( fun() -> - case qlc:e(qlc:q([ + case e(q([ {IP#ip_table.ban, IP#ip_table.ban_duration} || U <- mnesia:table(user), U#user.id =:= User_id, @@ -560,7 +565,7 @@ date_plus_minutes(Ban, Ban_duration) -> can_register(IP) -> resultat_transaction(mnesia:transaction( fun() -> - case qlc:e(qlc:q([I || I <- mnesia:table(ip_table), I#ip_table.ip =:= IP])) of + case e(q([I || I <- mnesia:table(ip_table), I#ip_table.ip =:= IP])) of [] -> mnesia:write(#ip_table{ip = IP, date_last_try_register = now()}), true; @@ -585,10 +590,18 @@ can_register(IP) -> trolls() -> resultat_transaction(mnesia:transaction( fun() -> - qlc:e(qlc:q([T || T <- qlc:keysort(2, mnesia:table(troll))])) + e(q([T || T <- qlc:keysort(2, mnesia:table(troll))])) end )). + +% Renvoie les trolls manquants posté après Last_id. +trolls(Last_id) -> + resultat_transaction(mnesia:transaction( + e(q([T || T <- qlc:keysort(2, mnesia:table(troll)), T#troll.id > Last_id, T#troll.date_post =:= undefined])) + )). + + % Renvoie les trolls manquants posté après Last_id. % Si pas de trolls alors attend un événement tel qu'un ajout, une modification ou une suppression. % renvoie : @@ -596,26 +609,31 @@ trolls() -> % ou {add, [Trolls]} % ou {del, Troll_id} % ou timeout -trolls(Last_id) -> +trolls_attente(Last_id) -> case mnesia:subscribe({table, troll, detailed}) of {error, E} = E -> E; _ -> - case resultat_transaction(mnesia:transaction( + R = case resultat_transaction(mnesia:transaction( fun() -> - qlc:e(qlc:q([T || T <- qlc:keysort(2, mnesia:table(troll)), T#troll.id > Last_id, T#troll.date_post =:= undefined])) + e(q([T || T <- qlc:keysort(2, mnesia:table(troll)), T#troll.id > Last_id, T#troll.date_post =:= undefined])) end )) of [] -> % pas de trolls attend_evenement_troll(); Trolls -> {add, Trolls} - end + end, + mnesia:unsubscribe({table, troll, detailed}), + R end. attend_evenement_troll() -> % s'il n'y a pas de trolls que l'utilisateur n'a pas connaissance alors on attend un événement receive + % cas où un troll est choisit comme courant + {mnesia_table_event, {write, troll, Troll, [Old_troll | _], _}} when Old_troll#troll.date_post =:= undefined, Troll#troll.date_post =/= undefined -> + {del, Troll#troll.id}; {mnesia_table_event, {write, troll, Troll, [_Old_troll | _], _}} -> {mod, Troll}; {mnesia_table_event, {write, troll, Troll, [], _}} -> @@ -637,14 +655,14 @@ put_troll(User_id, Content) -> resultat_transaction(mnesia:transaction( fun() -> % control le nombre de troll déjà posté - Nb_troll_poste_par_user = length(qlc:e(qlc:q( + Nb_troll_poste_par_user = length(e(q( [ E#troll.id || E <- mnesia:table(troll), E#troll.id_user =:= User_id, E#troll.date_post =:= undefined ] ))), - Nb_troll_poste_total = length(qlc:e(qlc:q( + Nb_troll_poste_total = length(e(q( [ E#troll.id || E <- mnesia:table(troll), E#troll.date_post =:= undefined @@ -699,7 +717,7 @@ del_troll(Troll_id) -> troll_by_id(Troll_id) -> resultat_transaction(mnesia:transaction( fun() -> - case qlc:e(qlc:q([T || T <- mnesia:table(troll), T#troll.id =:= Troll_id])) of + case e(q([T || T <- mnesia:table(troll), T#troll.id =:= Troll_id])) of [T] -> {ok, T}; _ -> erreur @@ -707,6 +725,44 @@ troll_by_id(Troll_id) -> end )). + +% Renvoie le troll actuel qui se trouve sur la page principale. +% Renvois aucun si pas de troll courant. +current_troll() -> + resultat_transaction(mnesia:transaction( + fun() -> + % TODO : ya pas moyen de désigner le champs plutot qu'avec un nombre pour le tri ? + C = cursor(q([T || T <- qlc:keysort(5, mnesia:table(troll), [{order, descending}]), T#troll.date_post =/= undefined])), + R = case qlc:next_answers(C, 1) of + [T] -> T; + _ -> aucun + end, + qlc:delete_cursor(C), + R + end + )). + + +% Elit un troll au hasard parmis les trolls en attente (leur date_post =:= undefined) +% met à jour sa date de post. +% renvoie plus_de_trolls si il n'y a aucun troll en attente. +elire_troll() -> + {A1,A2,A3} = now(), + random:seed(A1, A2, A3), + mnesia:transaction( + fun() -> + case e(q([T || T <- mnesia:table(troll), T#troll.date_post =:= undefined])) of + [] -> + plus_de_trolls; + Trolls -> + Troll = lists:nth(random:uniform(length(Trolls)), Trolls), + Troll2 = Troll#troll{date_post = now()}, + mnesia:write(Troll2) + end + end + ). + + update_version(1) -> mnesia:transform_table( diff --git a/modules/erl/euphorik_deamon.erl b/modules/erl/euphorik_deamon.erl new file mode 100755 index 0000000..0689203 --- /dev/null +++ b/modules/erl/euphorik_deamon.erl @@ -0,0 +1,22 @@ +% Module tournant en background s'occupant periodiquement de certaines tâches. +% Auteur : G.Burri +% Date : 05.11.2007 + +-module(euphorik_deamon). +-export([start/1]). + +-include("../include/euphorik_defines.hrl"). + + +% Démarre le démon +start(A) -> + loop(A). + + +loop(A) -> + euphorik_bd:elire_troll(), + timer:sleep(1000), + loop(A). + + + diff --git a/modules/erl/euphorik_minichat_conversation.erl b/modules/erl/euphorik_minichat_conversation.erl index d5f486f..0ce113c 100755 --- a/modules/erl/euphorik_minichat_conversation.erl +++ b/modules/erl/euphorik_minichat_conversation.erl @@ -26,38 +26,26 @@ % Chaque conversation est un tuple {[{Message, Parents}], Plus} où % Message est le message de type #minichat et Parents une liste d'Id. % Plus est un bool. Si Plus vaut true alors il y a encore des messages. -% Si il n'y a pas de nouveaux message alors la fonction est bloquante et attend un nouveau message. +% Si il n'y a pas de nouveaux message alors vide est renvoyé. % @spec conversations([{integer(), integer(), integer()}], integer(), integer(), integer()) -> [Conversation()] conversations(Racines, N, D, P) -> - % écoute des nouveaux messages - case mnesia:subscribe({table, minichat, simple}) of - {error, E} = E -> - E; - _ -> - % demande des conversations - Conversations = conversations_detailees(Racines, N, D, P), - % si les conversations sont vides alors on attend un nouveau message - Vide = not any( - fun(C) -> - case C of - {[], _} -> false; - {_, [], _, _} -> false; - _ -> true - end - end, - Conversations - ), - Conversations_mises_en_forme = mise_en_forme_conversations( - if Vide -> - attend_nouveau_message(), - conversations_detailees(Racines, N, D, P); - true -> - Conversations + Conversations = conversations_detailees(Racines, N, D, P), + % si les conversations sont vides alors on attend un nouveau message + Vide = not any( + fun(C) -> + case C of + {[], _} -> false; + {_, [], _, _} -> false; + _ -> true end - ), - mnesia:unsubscribe({table, minichat, simple}), - Conversations_mises_en_forme - end. + end, + Conversations + ), + if Vide -> + vide; + true -> + mise_en_forme_conversations(Conversations) + end. % Ecoute les événements de modification d'une table. @@ -86,22 +74,23 @@ conversations(Racines, N, D, P) -> % Attend qu'un nouveau message arrive, function bloquante. % Renvoie le nouveau message. +% Obsolète % @spec attend_nouveau_message() -> #minichat | timeout -attend_nouveau_message() -> - receive % attente d'un post - {mnesia_table_event, {write, Message, _}} -> - Message; - %file:close(F); +%~ attend_nouveau_message() -> + %~ receive % attente d'un post + %~ {mnesia_table_event, {write, Message, _}} -> + %~ Message; + %~ %file:close(F); %~ {tcp_closed, _} -> %~ mnesia:unsubscribe({table, minichat, simple}); - _ -> - attend_nouveau_message() + %~ _ -> + %~ attend_nouveau_message() % 60 minutes de timeout (le cas ou il n'y a que des consultations et jamais de post) % Après 60 minutes de connexion, le client doit donc reétablir une connexion % TODO : pour être mieux : quand le socket se ferme alors un message devrait être envoyé et débloquer ce receive (demande en cours sur la mailing list de yaws) - after 1000 * 60 * 60 -> - timeout - end. + %~ after 1000 * 60 * 60 -> + %~ timeout + %~ end. % Mise en forme des conversations pour l'utilisateur du module. diff --git a/modules/erl/euphorik_protocole.erl b/modules/erl/euphorik_protocole.erl index fcce9c3..cdd0f6b 100755 --- a/modules/erl/euphorik_protocole.erl +++ b/modules/erl/euphorik_protocole.erl @@ -66,10 +66,9 @@ loginUser({ok, User}, IP) -> euphorik_bd:update_date_derniere_connexion(User#user.id), json_reponse_login_ok(User); loginUser(_, _) -> - % ajoute un délais d'attente (TODO : un autre moyen plus élégant ?) - receive after 1000 -> - erreur("Erreur login") - end. + % ajoute un délais d'attente + timer:sleep(1000), + erreur("Erreur login"). % Renvoie un string() représentant un cookie en base 36. Il y a 10^32 possibillités. @@ -124,12 +123,14 @@ profile( % Renvoie les messages appropriés. % last_message id et cookie sont facultatifs wait_event([{page, "chat"} | Data]) -> + % traitement des inputs Cookie = case lists:keysearch(cookie, 1, Data) of {value, {_, C}} -> C; _ -> inconnu end, Last_message_id = case lists:keysearch(last_message_id, 1, Data) of {value, {_, Id}} -> Id; _ -> 0 end, {value, {_, Message_count}} = lists:keysearch(message_count, 1, Data), Main_page = case lists:keysearch(main_page, 1, Data) of {value, {_, P}} -> P; _ -> 1 end, + Troll_id = case lists:keysearch(troll_id, 1, Data) of {value, {_, T}} -> T; _ -> 0 end, {value, {_, {array, Conversations_json}}} = lists:keysearch(conversations, 1, Data), - Conversations = lists:map( + Racines_conversations = lists:map( fun({struct, [{root, Racine}, {page, Page} | Reste]}) -> Last_mess_conv = case Reste of [{last_message_id, L}] -> L; _ -> 0 end, {Racine, Page, Last_mess_conv} @@ -139,60 +140,19 @@ wait_event([{page, "chat"} | Data]) -> User = case euphorik_bd:user_by_cookie(Cookie) of {ok, U} -> U; _ -> inconnu - end, - {struct, [ - {reply, "new_message"}, - {conversations, {array, - % accrochez-vous ca va siouxer ;) - lists:map( - fun({Conv, Plus}) -> - {struct, [ - {last_page, not Plus}, - {messages, {array, - lists:map( - fun({Mess, Repond_a}) -> - Est_proprietaire = User =/= inconnu andalso User#user.id =:= Mess#minichat.auteur_id, - A_repondu_a_message = User =/= inconnu andalso euphorik_bd:a_repondu_a_message(User#user.id, Mess#minichat.id), - Est_une_reponse_a_user = User =/= inconnu andalso euphorik_bd:est_une_reponse_a_user(User#user.id, Mess#minichat.id), - {ok, User_mess } = euphorik_bd:user_by_id(Mess#minichat.auteur_id), - {struct, [ - {id, Mess#minichat.id}, - {user_id, User_mess#user.id}, - {date, format_date(Mess#minichat.date)}, - {system, Mess#minichat.auteur_id =:= 0}, - {owner, Est_proprietaire}, - {answered, A_repondu_a_message}, - {is_a_reply, Est_une_reponse_a_user}, - {nick, Mess#minichat.pseudo}, - {login, User_mess#user.login}, - {content, Mess#minichat.contenu}, - {answer_to, {array, lists:map( - fun(Id_mess) -> - {ok, M} = euphorik_bd:message_by_id(Id_mess), - {ok, User_reponse} = euphorik_bd:user_by_mess(M#minichat.id), - {struct, [{id, M#minichat.id}, {nick, M#minichat.pseudo}, {login, User_reponse#user.login}]} - end, - Repond_a - )}}, - {ek_master, User_mess#user.ek_master} - ]} - end, - Conv - ) - }} - ]} - end, - euphorik_minichat_conversation:conversations( - Conversations, - Message_count, - Last_message_id, - Main_page - ) - ) - }} - ]}; + end, + case {mnesia:subscribe({table, minichat, detailed}), mnesia:subscribe({table, troll, detailed})} of + {{error, E}, _} -> E; + {_, {error, E}} -> E; + _ -> + % attente d'événements + R = wait_event_page_chat(User, Racines_conversations, Message_count, Last_message_id, Main_page, Troll_id), + mnesia:unsubscribe({table, minichat, detailed}), + mnesia:unsubscribe({table, troll, detailed}), + R + end; wait_event([{page, "admin"}, {last_troll, Last_troll}]) -> - case euphorik_bd:trolls(Last_troll) of + case euphorik_bd:trolls_attente(Last_troll) of {mod, Troll} -> {struct, [ @@ -235,7 +195,91 @@ wait_event([{page, "admin"}, {last_troll, Last_troll}]) -> end; wait_event(_) -> erreur("Page inconnue"). - + + +wait_event_page_chat(User, Racines_conversations, Message_count, Last_message_id, Main_page, Troll_id) -> + % est-ce qu'il y a des nouveaux messages ? + case euphorik_minichat_conversation:conversations(Racines_conversations, Message_count, Last_message_id, Main_page) of + vide -> + % est-ce que le troll est à jour ? + case euphorik_bd:current_troll() of + Current when is_record(Current, troll), Current#troll.id =/= Troll_id -> + {struct, [ + {reply, "new_troll"}, + {troll_id, Current#troll.id}, + {content, Current#troll.content} + ]}; + _ -> + wait_event_bd_page_chat(), + % TODO : l'appel est-il bien tail-recursive ? + wait_event_page_chat(User, Racines_conversations, Message_count, Last_message_id, Main_page, Troll_id) + end; + Conversations -> + % accrochez-vous ca va siouxer ;) + {struct, [ + {reply, "new_messages"}, + {conversations, {array, + lists:map( + fun({Conv, Plus}) -> + {struct, [ + {last_page, not Plus}, + {messages, {array, + lists:map( + fun({Mess, Repond_a}) -> + Est_proprietaire = User =/= inconnu andalso User#user.id =:= Mess#minichat.auteur_id, + A_repondu_a_message = User =/= inconnu andalso euphorik_bd:a_repondu_a_message(User#user.id, Mess#minichat.id), + Est_une_reponse_a_user = User =/= inconnu andalso euphorik_bd:est_une_reponse_a_user(User#user.id, Mess#minichat.id), + {ok, User_mess } = euphorik_bd:user_by_id(Mess#minichat.auteur_id), + {struct, [ + {id, Mess#minichat.id}, + {user_id, User_mess#user.id}, + {date, format_date(Mess#minichat.date)}, + {system, Mess#minichat.auteur_id =:= 0}, + {owner, Est_proprietaire}, + {answered, A_repondu_a_message}, + {is_a_reply, Est_une_reponse_a_user}, + {nick, Mess#minichat.pseudo}, + {login, User_mess#user.login}, + {content, Mess#minichat.contenu}, + {answer_to, {array, lists:map( + fun(Id_mess) -> + {ok, M} = euphorik_bd:message_by_id(Id_mess), + {ok, User_reponse} = euphorik_bd:user_by_mess(M#minichat.id), + {struct, [{id, M#minichat.id}, {nick, M#minichat.pseudo}, {login, User_reponse#user.login}]} + end, + Repond_a + )}}, + {ek_master, User_mess#user.ek_master} + ]} + end, + Conv + ) + }} + ]} + end, + Conversations + ) + }} + ]} + end. + + +% Attend un événement lié à la page 'chat'. +wait_event_bd_page_chat() -> + receive % attente d'un post + {mnesia_table_event, {write, minichat, _Message, [], _}} -> + ok; + {mnesia_table_event, {write, troll, Troll, [Old_troll | _], _}} when Troll#troll.date_post =/= undefined, Old_troll#troll.date_post == undefined -> + ok; + _ -> + wait_event_bd_page_chat() + % 60 minutes de timeout (le cas ou il n'y a que des consultations et jamais de post) + % Après 60 minutes de connexion, le client doit donc reétablir une connexion + % TODO : pour être mieux : quand le socket se ferme alors un message devrait être envoyé et débloquer ce receive (demande en cours sur la mailing list de yaws) + after 1000 * 60 * 60 -> + timeout + end. + % Un utilisateur envoie un message put_message( -- 2.43.0