X-Git-Url: http://git.euphorik.ch/index.cgi?a=blobdiff_plain;f=modules%2Ferl%2Feuphorik_protocole.erl;fp=modules%2Ferl%2Feuphorik_protocole.erl;h=ad65d1a6e396a97c2383ddbea3e3c7bdc2f781c4;hb=79f0cfc91b7220d98e4caf50fbb3857807fc6bc4;hp=947a18ba25d609b51fa495ae3db7238d121c0a87;hpb=afc7c6e84fac05e989a208f72538e6a55daa758f;p=euphorik.git diff --git a/modules/erl/euphorik_protocole.erl b/modules/erl/euphorik_protocole.erl index 947a18b..ad65d1a 100755 --- a/modules/erl/euphorik_protocole.erl +++ b/modules/erl/euphorik_protocole.erl @@ -15,7 +15,7 @@ % % You should have received a copy of the GNU General Public License % along with Euphorik. If not, see . -% +% % Ce module gére les différents messages envoyés par le client (javascript) via AJAX. % Les messages donnés ainsi que les réponses sont au format JSON. % @author G.Burri @@ -42,7 +42,7 @@ % Une utilisateur s'enregistre avec un tuple {Login, Password}. -register([{login, Login}, {password, Password}, {profile, Profile_json}], IP) -> +register([{"login", Login}, {"password", Password}, {"profile", Profile_json}], IP) -> Can_register = euphorik_bd:can_register(IP), if Can_register -> case euphorik_bd:user_by_login(Login) of @@ -57,7 +57,7 @@ register([{login, Login}, {password, Password}, {profile, Profile_json}], IP) -> erreur_register_flood() end; % Enregistrement sans {Login, Password} -register([{profile, Profile_json}], IP) -> +register([{"profile", Profile_json}], IP) -> Can_register = euphorik_bd:can_register(IP), if Can_register -> Profile = profile_from_json(Profile_json), @@ -67,22 +67,22 @@ register([{profile, Profile_json}], IP) -> true -> erreur_register_flood() end. - + erreur_register_flood() -> erreur(20). - + % Un utilisateur se logge (avec un couple {login, mot de passe}) -login([{login, Login}, {password, Password}], IP) -> +login([{"login", Login}, {"password", Password}], IP) -> case euphorik_bd:user_by_login_password(Login, Password) of {ok, User} -> loginUser(User, IP); - _ -> + _ -> timer:sleep(?TEMPS_ATTENTE_ERREUR_LOGIN), erreur(30) end; % Un utilisateur se logge (avec un cookie) -login([{cookie, Cookie}], IP) -> +login([{"cookie", Cookie}], IP) -> case euphorik_bd:user_by_cookie(Cookie) of {ok, User} -> loginUser(User, IP); @@ -90,18 +90,18 @@ login([{cookie, Cookie}], IP) -> timer:sleep(?TEMPS_ATTENTE_ERREUR_LOGIN), erreur(40) end. - - + + % L'utilisateur donné se logge avec l'ip donnée. loginUser(User, IP) -> euphorik_bd:update_ip(User#user.id, IP), euphorik_bd:update_date_derniere_connexion(User#user.id), json_reponse_login_ok(User). - - + + % Renvoie un string() représentant un cookie en base 36. Il y a 10^32 possibillités. generer_cookie() -> - {A1, A2, A3} = now(), + {A1, A2, A3} = erlang:timestamp(), random:seed(A1, A2, A3), erlang:integer_to_list(random:uniform(trunc(math:pow(10, 32))), 36). @@ -109,10 +109,10 @@ generer_cookie() -> % Modification du profile. profile( [ - {cookie, Cookie}, - {login, Login}, - {password, Password}, - {profile, Profile_json} + {"cookie", Cookie}, + {"login", Login}, + {"password", Password}, + {"profile", Profile_json} ] ) -> case profile_from_json(Profile_json) of @@ -133,21 +133,21 @@ profile( profile_from_json( {struct, [ - {nick, Pseudo}, - {email, Email}, - {css, Css}, - {chat_order, Chat_order_str}, - {nick_format, Nick_format_str}, - {view_times, View_times}, - {view_tooltips, View_tooltips}, - {conversations, {array, Conversations_json}}, - {ostentatious_master, Ostentatious_master_str} + {"nick", Pseudo}, + {"email", Email}, + {"css", Css}, + {"chat_order", Chat_order_str}, + {"nick_format", Nick_format_str}, + {"view_times", View_times}, + {"view_tooltips", View_tooltips}, + {"conversations", {array, Conversations_json}}, + {"ostentatious_master", Ostentatious_master_str} ] } ) -> % décomposition de la strucure JSON Conversations = lists:foldr( - fun({struct, [{root, Racine}, {minimized, Reduit}]}, A) -> + fun({struct, [{"root", Racine}, {"minimized", Reduit}]}, A) -> % virage des messages qui n'existent pas Message_exite = euphorik_bd:message_existe(Racine), if Message_exite -> @@ -164,12 +164,12 @@ profile_from_json( Chat_order_valide = lists:any(fun(E) -> E =:= Chat_order end, [reverse, chrono]), if not Chat_order_valide -> {erreur, Chat_order_str ++ " n'est pas une valeur acceptée pour 'chat_order'"}; - true -> + true -> Nick_format = list_to_atom(Nick_format_str), Nick_format_valide = lists:any(fun(E) -> E =:= Nick_format end, [nick, login, nick_login]), if not Nick_format_valide -> {erreur, Nick_format_str ++ " n'est pas une valeur acceptée pour 'nick_format'"}; - true -> + true -> Ostentatious_master = list_to_atom(Ostentatious_master_str), Ostentatious_master_valide = lists:any(fun(E) -> E =:= Ostentatious_master end, [invisible, light, heavy]), if not Ostentatious_master_valide -> @@ -187,23 +187,24 @@ profile_from_json( ostentatious_master = Ostentatious_master } end - end + end end. % Attend un événement pour la page "Chat" % last_message id et cookie sont facultatifs -wait_event([{page, "chat"} | Data]) -> +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), + 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), + Racines_conversations = lists:map( - fun({struct, [{root, Racine}, {page, Page} | Reste]}) -> - Last_mess_conv = case Reste of [{last_message_id, L}] -> L; _ -> 0 end, + 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} end, Conversations_json @@ -212,6 +213,7 @@ wait_event([{page, "chat"} | Data]) -> {ok, U} -> U; _ -> inconnu end, + case {mnesia:subscribe({table, minichat, detailed}), mnesia:subscribe({table, troll, detailed})} of {{error, E}, _} -> E; {_, {error, E}} -> E; @@ -223,36 +225,36 @@ wait_event([{page, "chat"} | Data]) -> R end; % Attend un événement pour la page "Admin" -wait_event([{page, "admin"}, {last_troll, Last_troll}]) -> +wait_event([{"page", "admin"}, {"last_troll", Last_troll}]) -> case wait_event_page_admin(Last_troll) of banned_ips_refresh -> - {struct, + {struct, [ - {reply, "banned_ips_refresh"} + {"reply", "banned_ips_refresh"} ] }; {mod, Troll} -> {struct, [ - {reply, "troll_modified"}, - {troll_id, Troll#troll.id}, - {content, Troll#troll.content} + {"reply", "troll_modified"}, + {"troll_id", Troll#troll.id}, + {"content", Troll#troll.content} ] }; {add, Trolls} -> {struct, [ - {reply, "troll_added"}, - {trolls, {array, + {"reply", "troll_added"}, + {"trolls", {array, lists:map( - fun(T) -> + fun(T) -> {ok, #user{profile = Profile} = User} = euphorik_bd:user_by_id(T#troll.id_user), {struct, [ - {troll_id, T#troll.id}, - {content, T#troll.content}, - {author, Profile#profile.pseudo}, - {author_id, User#user.id} + {"troll_id", T#troll.id}, + {"content", T#troll.content}, + {"author", Profile#profile.pseudo}, + {"author_id", User#user.id} ] } end, @@ -260,14 +262,14 @@ wait_event([{page, "admin"}, {last_troll, Last_troll}]) -> ) }} ] - }; + }; {del, Troll_id} -> {struct, [ - {reply, "troll_deleted"}, - {troll_id, Troll_id} + {"reply", "troll_deleted"}, + {"troll_id", Troll_id} ] - }; + }; _ -> erreur(60) end; @@ -281,27 +283,27 @@ wait_event_page_chat(User, Racines_conversations, Message_count, Last_message_id 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}, - {message_id, Current#troll.id_minichat}, - {content, Current#troll.content} + {"reply", "new_troll"}, + {"troll_id", Current#troll.id}, + {"message_id", Current#troll.id_minichat}, + {"content", Current#troll.content} ]}; _ -> % 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 -> + vide -> wait_event_bd_page_chat(), wait_event_page_chat(User, Racines_conversations, Message_count, Last_message_id, Main_page, Troll_id); Conversations -> % accrochez-vous ca va siouxer ;) {struct, [ - {reply, "new_messages"}, - {conversations, {array, + {"reply", "new_messages"}, + {"conversations", {array, lists:map( fun({Racine, {Conv, Plus}}) -> {struct, [ - {last_page, not Plus}, - {first, % le premier message de la conversation + {"last_page", not Plus}, + {"first", % le premier message de la conversation if Racine =:= undefined orelse Conv =:= [] -> null; true -> @@ -332,14 +334,14 @@ wait_event_page_chat(User, Racines_conversations, Message_count, Last_message_id ]} end end. - -aggregation_racines_conversations(L1, L2) -> + +aggregation_racines_conversations(L1, L2) -> aggregation_racines_conversations(L1, L2, []). aggregation_racines_conversations([], [], L) -> lists:reverse(L); aggregation_racines_conversations([E1|R1], [E2|R2], L) -> aggregation_racines_conversations(R1, R2, [{E1, E2} | L]). - + % Attend un événement lié à la page 'chat'. @@ -355,7 +357,7 @@ wait_event_bd_page_chat() -> wait_event_bd_page_chat() % 60 minutes de timeout (on ne sais jamais) % Après 60 minutes de connexion, le client doit donc reétablir une connexion - after 1000 * 60 * 60 -> + after 1000 * 60 * 60 -> timeout end. @@ -384,7 +386,7 @@ wait_event_page_admin(Last_id) -> mnesia:unsubscribe({table, ip_table, detailed}), R end. - + wait_event_page_admin() -> % s'il n'y a pas de trolls que l'utilisateur n'a pas connaissance alors on attend un événement receive @@ -407,19 +409,19 @@ wait_event_page_admin() -> wait_event_page_admin() % 60 minutes de timeout (on ne sais jamais) % Après 60 minutes de connexion, le client doit donc reétablir une connexion - after 1000 * 60 * 60 -> + after 1000 * 60 * 60 -> timeout end. - - + + % Un utilisateur envoie un message % Answer_to est une liste d'id (int) put_message( [ - {cookie, Cookie}, - {nick, Nick}, - {content, Content}, - {answer_to, {array, Answer_to}} + {"cookie", Cookie}, + {"nick", Nick}, + {"content", Content}, + {"answer_to", {array, Answer_to}} ] ) -> case euphorik_bd:user_by_cookie(Cookie) of @@ -449,10 +451,10 @@ put_message( % bannissement d'un utilisateur (son ip est bannie) ban( [ - {cookie, Cookie}, - {duration, Duration}, - {user_id, User_id}, - {reason, Reason} + {"cookie", Cookie}, + {"duration", Duration}, + {"user_id", User_id}, + {"reason", Reason} ]) -> % controle que l'utilisateur est un admin case euphorik_bd:user_by_cookie(Cookie) of @@ -480,21 +482,21 @@ ban( _ -> erreur(150) end. - + % slapage d'un user (avertissement) slap( [ - {cookie, Cookie}, - {user_id, User_id}, - {reason, Reason} + {"cookie", Cookie}, + {"user_id", User_id}, + {"reason", Reason} ]) -> % controle que l'utilisateur est un admin case euphorik_bd:user_by_cookie(Cookie) of {ok, User1 = #user{ek_master = true, profile = Profile1}} -> case euphorik_bd:user_by_id(User_id) of {ok, User1} -> - euphorik_bd:nouveau_message_sys(lists:flatten(io_lib:format("~s s'auto slap~s.", + euphorik_bd:nouveau_message_sys(lists:flatten(io_lib:format("~s s'auto slap~s.", [ Profile1#profile.pseudo, if Reason =/= [] -> " - Raison: " ++ Reason; true -> "" end @@ -518,12 +520,12 @@ slap( _ -> erreur(170) end. - - + + put_troll( [ - {cookie, Cookie}, - {content, Content} + {"cookie", Cookie}, + {"content", Content} ] ) -> % controle que l'utilisateur est un admin @@ -540,13 +542,13 @@ put_troll( _ -> erreur(200) end. - - + + mod_troll( [ - {cookie, Cookie}, - {troll_id, Troll_id}, - {content, Content} + {"cookie", Cookie}, + {"troll_id", Troll_id}, + {"content", Content} ] ) -> % controle que l'utilisateur est un admin @@ -564,13 +566,13 @@ mod_troll( erreur(220) end. - + del_troll( [ - {cookie, Cookie}, - {troll_id, Troll_id} + {"cookie", Cookie}, + {"troll_id", Troll_id} ] -) -> +) -> % controle que l'utilisateur est un admin case euphorik_bd:user_by_cookie(Cookie) of {ok, User = #user{ek_master = true}} -> @@ -585,12 +587,12 @@ del_troll( _ -> erreur(220) end. - - + + unban_ip( [ - {cookie, Cookie}, - {ip, IP} + {"cookie", Cookie}, + {"ip", IP} ] ) -> case euphorik_bd:user_by_cookie(Cookie) of @@ -600,11 +602,11 @@ unban_ip( _ -> erreur(230) end. - - + + list_banned_ips( [ - {cookie, Cookie} + {"cookie", Cookie} ] ) -> case euphorik_bd:user_by_cookie(Cookie) of @@ -612,19 +614,19 @@ list_banned_ips( { struct, [ - {reply, "list_banned_ips"}, - {list, {array, lists:map( + {"reply", "list_banned_ips"}, + {"list", {array, lists:map( fun({IP, T, Users}) -> {struct, [ - {ip, euphorik_common:serialize_ip(IP)}, - {remaining_time, format_minutes(T)}, - {users, {array, lists:map( + {"ip", euphorik_common:serialize_ip(IP)}, + {"remaining_time", format_minutes(T)}, + {"users", {array, lists:map( fun({Pseudo, Login}) -> {struct, [ - {nick, Pseudo}, - {login, Login} + {"nick", Pseudo}, + {"login", Login} ] } end, @@ -645,22 +647,22 @@ list_banned_ips( % Construit une erreur erreur(Num, Args) -> erreur_json(Num, lists:flatten(io_lib:format(euphorik_bd:get_texte(Num), Args))). - - + + erreur(Num) -> erreur_json(Num, euphorik_bd:get_texte(Num)). - - + + erreur_json(Num, Mess) -> { struct, [ - {reply, "error"}, - {no, Num}, - {error_message, Mess} + {"reply", "error"}, + {"no", Num}, + {"error_message", Mess} ] }. - - + + % Formatage de minutes. % par exemple : "1min", "45min", "1h23min", "1jour 2h34min" format_minutes(Min) -> @@ -674,8 +676,8 @@ format_minutes(Min) -> true -> " " ++ integer_to_list(Minutes) ++ " minute" ++ if Minutes > 1 -> "s"; true -> "" end end. - - + + % Formatage d'une heure % local_time() -> string format_date(Date) -> @@ -690,7 +692,7 @@ format_date(Date) -> Hier -> "Hier "; Annee =:= AnneeNow -> - io_lib:format("~2.10.0B/~2.10.0B ", [Jour, Mois]); + io_lib:format("~2.10.0B/~2.10.0B ", [Jour, Mois]); true -> io_lib:format("~2.10.0B/~2.10.0B/~B ", [Jour, Mois, Annee]) end ++ @@ -699,39 +701,39 @@ format_date(Date) -> json_reponse_ok() -> - {struct, [{reply, "ok"}]}. - - + {struct, [{"reply", "ok"}]}. + + json_reponse_login_ok(#user{profile = Profile} = User) -> { struct, [ - {reply, "login"}, - {status, if (User#user.password =/= []) and (User#user.login =/= []) -> "auth_registered"; true -> "auth_not_registered" end}, - {cookie, User#user.cookie}, - {id, User#user.id}, - {login, User#user.login}, - {ek_master, User#user.ek_master}, - {profile, {struct, + {"reply", "login"}, + {"status", if (User#user.password =/= []) and (User#user.login =/= []) -> "auth_registered"; true -> "auth_not_registered" end}, + {"cookie", User#user.cookie}, + {"id", User#user.id}, + {"login", User#user.login}, + {"ek_master", User#user.ek_master}, + {"profile", {struct, [ - {nick, Profile#profile.pseudo}, - {email, Profile#profile.email}, - {css, Profile#profile.css}, - {chat_order, atom_to_list(Profile#profile.chat_order)}, - {nick_format, atom_to_list(Profile#profile.nick_format)}, - {view_times, Profile#profile.view_times}, - {view_tooltips, Profile#profile.view_tooltips}, - {conversations, {array, lists:map( + {"nick", Profile#profile.pseudo}, + {"email", Profile#profile.email}, + {"css", Profile#profile.css}, + {"chat_order", atom_to_list(Profile#profile.chat_order)}, + {"nick_format", atom_to_list(Profile#profile.nick_format)}, + {"view_times", Profile#profile.view_times}, + {"view_tooltips", Profile#profile.view_tooltips}, + {"conversations", {array, lists:map( fun({Racine, Reduit}) -> - {struct, [{root, Racine}, {minimized, Reduit}]} + {struct, [{"root", Racine}, {"minimized", Reduit}]} end, Profile#profile.conversations )}}, - {ostentatious_master, atom_to_list(Profile#profile.ostentatious_master)} + {"ostentatious_master", atom_to_list(Profile#profile.ostentatious_master)} ] }} ] }. - + % Renvoie le message formaté en JSON. % Mess est de type #minichat % Repond_a est une liste d'id des messages auquel répond Mess @@ -742,25 +744,25 @@ json_message(Mess, Repond_a, User) -> Est_une_reponse_a_user = User =/= inconnu andalso euphorik_bd:est_une_reponse_a_user(User#user.id, Mess#minichat.id), {ok, #user{profile = Profile_mess} = User_mess } = euphorik_bd:user_by_id(Mess#minichat.auteur_id), {struct, [ - {id, Mess#minichat.id}, - {user_id, User_mess#user.id}, - {date, case Mess#minichat.date of undefined -> "?"; _ -> format_date(Mess#minichat.date) end}, - {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}, - {root, Mess#minichat.racine_id}, - {answer_to, {array, lists:map( - fun(Id_mess) -> + {"id", Mess#minichat.id}, + {"user_id", User_mess#user.id}, + {"date", case Mess#minichat.date of undefined -> "?"; _ -> format_date(Mess#minichat.date) end}, + {"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}, + {"root", Mess#minichat.racine_id}, + {"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}]} + {struct, [{"id", M#minichat.id}, {"nick", M#minichat.pseudo}, {"login", User_reponse#user.login}]} end, Repond_a )}}, - {ek_master, User_mess#user.ek_master}, - {ostentatious_master, atom_to_list(Profile_mess#profile.ostentatious_master)} + {"ek_master", User_mess#user.ek_master}, + {"ostentatious_master", atom_to_list(Profile_mess#profile.ostentatious_master)} ]}.