X-Git-Url: http://git.euphorik.ch/?p=euphorik.git;a=blobdiff_plain;f=modules%2Ferl%2Feuphorik_bd.erl;h=196a26e25f94cdccce7f651e79c41c7fdfe0a8a0;hp=be46ab249c9635ca61d5e2f1e8bf61ee1272e0ad;hb=4dfbbcf0f54cb3eb70856ea404d9ecef6aec5e26;hpb=c4a3bf46b1974dce83a6333390dd97a800070b59 diff --git a/modules/erl/euphorik_bd.erl b/modules/erl/euphorik_bd.erl index be46ab2..196a26e 100755 --- a/modules/erl/euphorik_bd.erl +++ b/modules/erl/euphorik_bd.erl @@ -23,30 +23,21 @@ -module(euphorik_bd). --export([ - % gestion : - create/0, - connect/0, - connect/1, - reset/0, - +-export([ % users : nouveau_user/2, - nouveau_user/3, - set_profile/10, + nouveau_user/4, + set_profile/4, update_date_derniere_connexion/1, update_ip/2, update_pseudo_user/2, - print_users/0, - print_users/1, - print_user/1, user_by_cookie/1, user_by_id/1, user_by_login/1, user_by_login_password/2, user_by_mess/1, - toggle_ek_master/1, css_from_user_cookie/1, + is_ek_master_from_cookie/1, % messages :e nouveau_message/3, @@ -94,86 +85,11 @@ -include_lib("stdlib/include/qlc.hrl"). -% Instructions pour créer une nouvelle base : -% $erl -sname yaws -mnesia dir '"/projets/euphorik/BD"' -% voir doc/installation.txt -% >l(euphorik_bd). -% >euphorik_bd:create(). -create() -> - mnesia:stop(), - mnesia:delete_schema([node()]), - mnesia:create_schema([node()]), % nécessaire pour les tables sur disc - mnesia:start(), - create_tables(), - reset(). - -create_tables() -> - mnesia:create_table(counter, [ - {attributes, record_info(fields, counter)}, - {disc_copies, [node()]} - ]), - mnesia:create_table(proprietes, [ - {attributes, record_info(fields, proprietes)}, - {disc_copies, [node()]} - ]), - mnesia:create_table(minichat, [ - {attributes, record_info(fields, minichat)}, - {index, [auteur_id, troll_id]}, - {disc_copies, [node()]} - ]), - mnesia:create_table(reponse_minichat, [ - {type, bag}, - {attributes, record_info(fields, reponse_minichat)}, - {index, [cible]}, - {disc_copies, [node()]} - ]), - mnesia:create_table(user, [ - {attributes, record_info(fields, user)}, - {index, [cookie, login]}, - {disc_copies, [node()]} - ]), - mnesia:create_table(ip_table, [ - {attributes, record_info(fields, ip_table)}, - {disc_copies, [node()]} - ]), - mnesia:create_table(troll, [ - {attributes, record_info(fields, troll)}, - {index, [date_post]}, - {disc_copies, [node()]} - ]). - - -% Connexion à la base de données de yaws sur overnux -connect() -> - connect(yaws@flynux). -connect(Node) -> - mnesia:start(), - mnesia:change_config(extra_db_nodes, [Node]). - - -% Efface tous les users, minichat_reponse et minichat. -reset() -> - mnesia:clear_table(counter), - mnesia:clear_table(proprietes), - mnesia:clear_table(user), - mnesia:clear_table(reponse_minichat), - mnesia:clear_table(minichat), - mnesia:clear_table(troll), - mnesia:clear_table(ip_table), - % crée l'utilisateur root - mnesia:transaction(fun() -> - mnesia:write(#proprietes{nom = version, valeur = ?VERSION_BD}), - User = #user{id = 0, pseudo = "Sys", login = "Sys", date_creation = now(), date_derniere_connexion = now(), ek_master = true}, - mnesia:write(User), - User - end). - - % Ajoute un nouveau user et le renvoie -nouveau_user(Pseudo, Cookie) -> +nouveau_user(Cookie, Profile) -> F = fun() -> Id = nouvel_id(user), - User = #user{id = Id, cookie = Cookie, pseudo = Pseudo, date_creation = now(), date_derniere_connexion = now()}, + User = #user{id = Id, cookie = Cookie, date_creation = now(), date_derniere_connexion = now(), profile = Profile}, mnesia:write(User), User end, @@ -181,50 +97,39 @@ nouveau_user(Pseudo, Cookie) -> % Ajoute un nouveau user et le renvoie -nouveau_user(Login, Password, Cookie) -> +nouveau_user(Login, Password, Cookie, Profile) -> F = fun() -> Id = nouvel_id(user), - User = #user{id = Id, cookie = Cookie, pseudo = Login, login = Login, password = Password, date_creation = now(), date_derniere_connexion = now()}, + User = #user{id = Id, cookie = Cookie, login = Login, password = Password, date_creation = now(), date_derniere_connexion = now(), profile = Profile#profile{pseudo = Login}}, mnesia:write(User), User end, resultat_transaction(mnesia:transaction(F)). + - -% Mise à par Cookie les autres peuvent être undefined ce qui veut dire qu'ils ne seront pas modifié. -set_profile(Cookie, Login, Password, Pseudo, Email, Css, Nick_format, View_times, View_tooltips, Conversations) -> - if Nick_format =:= nick; Nick_format =:= login; Nick_format =:= nick_login -> - resultat_transaction(mnesia:transaction( - fun() -> - case user_by_cookie(Cookie) of - {ok, User} -> - case user_by_login(Login) of - {ok, U} when Login =/= [], U#user.id =/= User#user.id -> - login_deja_pris; - _ -> - User_modifie = User#user{ - % TODO : pourquoi ne pas tester avec la valeur "undefined" plutôt qu'avec "is_list" ? - % TODO : validation plus strict des données (pas de page négative dans les conv par exemple) - login = if is_list(Login) -> Login; true -> User#user.login end, - password = if is_list(Password) andalso Password =/= [] -> Password; true -> User#user.password end, - pseudo = if is_list(Pseudo) -> Pseudo; true -> User#user.pseudo end, - email = if is_list(Email) -> Email; true -> User#user.email end, - css = if is_list(Css) -> Css; true -> User#user.css end, - nick_format = Nick_format, - view_times = View_times, - view_tooltips = View_tooltips, - conversations = if is_list(Conversations) -> Conversations; true -> User#user.conversations end - }, - mnesia:write(User_modifie), - ok - end; - _ -> erreur - end - end - )); - true -> - erreur - end. +% Définit les données du profile d'une utilisateur. +set_profile(Cookie, Login, Password, Profile) -> + resultat_transaction(mnesia:transaction( + fun() -> + case user_by_cookie(Cookie) of + {ok, User_existant} -> + case user_by_login(Login) of + {ok, U} when Login =/= [], U#user.id =/= User_existant#user.id -> + login_deja_pris; + _ -> + mnesia:write( + User_existant#user{ + login = if User_existant#user.login =:= [] -> Login; true -> User_existant#user.login end, % on ne peut pas changer de login sauf si on en a pas ! + password = if Password =:= [] -> User_existant#user.password; true -> Password end, + profile = Profile + } + ), + ok + end; + _ -> erreur + end + end + )). % Met à jour la date de la dernière connexion d'un utilisateur à maintenant @@ -238,7 +143,7 @@ update_date_derniere_connexion(User_id) -> mnesia:abort("update_date_derniere_connexion: User inconnu") end end - ). + ). % Met à jour l'ip d'un user @@ -260,83 +165,14 @@ update_pseudo_user(UserId, Pseudo) -> mnesia:transaction( fun() -> case mnesia:wread({user, UserId}) of - [User] when User#user.pseudo =/= Pseudo -> - mnesia:write(User#user{pseudo = Pseudo}); + [#user{profile = Profile} = User] when Profile#profile.pseudo =/= Pseudo -> + mnesia:write(User#user{profile = Profile#profile { pseudo = Pseudo } }); _ -> mnesia:abort("update_pseudo_user: User inconnu ou pseudo deja à jour") end end ). - - -% Affiche N user trié par leur date de dernière connexion. -% Opt est une liste d'option d'affichage : -% * ekmaster : n'affiche que les admins -print_users(N, Opt) -> - AfficheQueLesEkMaster = lists:any(fun(O) -> O =:= ekmaster end, Opt), - resultat_transaction(mnesia:transaction(fun() -> - C = cursor( - qlc:keysort( - #user.date_derniere_connexion, - if AfficheQueLesEkMaster -> - q([E || E <- mnesia:table(user), E#user.ek_master =:= true]); - true -> - q([E || E <- mnesia:table(user)]) - end, - [{order, descending}] - ), - [{tmpdir, ?KEY_SORT_TEMP_DIR}] - ), - Users = qlc:next_answers(C, N), - lists:foreach( - fun(U) -> - print_user(U) - end, - Users - ), - qlc:delete_cursor(C) - end)). - - -% Affiche tous les users. -print_users(Opt) -> - print_users(all_remaining, Opt). - -% Affiche tous les users. -print_users() -> - print_users(all_remaining, []). - -print_user(User) when is_record(User, user) -> - #user{id = Id, pseudo = Pseudo, login = Login, ek_master = Ek_master, date_derniere_connexion = Date, last_ip = IP} = User, - {{Annee, Mois, Jour}, {Heure, Min, _}} = calendar:now_to_local_time(Date), - io:format( - % id pseudo (login) IP Jour Mois Année Heure Minute - "~4w : ~10.10..s(~10.10..s) ~s ~2w.~2.2.0w.~w - ~2wh~2.2.0w~n", - [ - Id, - if Ek_master -> "*"; true -> "" end ++ Pseudo, - Login, - euphorik_common:serialize_ip(IP), - Jour, Mois, Annee, Heure, Min - ] - ); -% Affichage d'un user en fonction de son login -print_user(Login) when is_list(Login) -> - case user_by_login(Login) of - {ok, User} -> - print_user(User); - _ -> - {erreur, "Login pas trouvé : " ++ Login} - end; -% Affichage d'un user en fonction de son id -print_user(Id) when is_integer(Id) -> - case user_by_id(Id) of - {ok, User} -> - print_user(User); - _ -> - {erreur, "Id pas trouvé : " ++ integer_to_list(Id)} - end. - + % Est-ce qu'un utilisateur existe en fonction de son cookie ? % Renvoie {ok, User} ou erreur @@ -373,29 +209,23 @@ user_by_login(Login) -> end )). - -toggle_ek_master(User_id) -> - resultat_transaction(mnesia:transaction( - fun() -> - Users = e(q([E || E <- mnesia:table(user), E#user.id =:= User_id]), [{tmpdir, ?KEY_SORT_TEMP_DIR}]), - case Users of - [User] -> - mnesia:write(User#user{ek_master = not User#user.ek_master}); - _ -> erreur - end - end - )). - % Renvoie une chaine représentant le cookie ou undefined si pas trouvé. css_from_user_cookie(Cookie) -> case user_by_cookie(Cookie) of - {ok, User} -> - User#user.css; + {ok, #user{profile = Profile}} -> + Profile#profile.css; _ -> undefined end. + +is_ek_master_from_cookie(Cookie) -> + case user_by_cookie(Cookie) of + {ok, #user{ek_master = true}} -> true; + _ -> false + end. + user_by_login_password(Login, Password) -> resultat_transaction(mnesia:transaction( @@ -446,7 +276,7 @@ nouveau_message(Mess, Auteur_id, Repond_A_ids) -> _ -> % est-ce que l'auteur existe ? case e(q([E || E <- mnesia:table(user), E#user.id =:= Auteur_id]), [{tmpdir, ?KEY_SORT_TEMP_DIR}]) of - [Auteur] -> + [#user{profile = Profile} = Auteur] -> if length(Repond_a) =/= length(Repond_A_ids) -> {erreur, "Un ou plusieurs messages introuvable"}; true -> @@ -460,7 +290,7 @@ nouveau_message(Mess, Auteur_id, Repond_A_ids) -> % est-ce que l'auteur à trop floodé ? if Auteur#user.indice_flood =/= ?INDICE_SPAM_MAX, Auteur_maj#user.indice_flood =:= ?INDICE_SPAM_MAX, Delta =< ?DUREE_BLOCAGE_SPAM -> mnesia:write(Auteur#user{indice_flood = Auteur_maj#user.indice_flood}), - nouveau_message_sys("''" ++ Auteur#user.pseudo ++ if Auteur#user.login =/= [] -> " (" ++ Auteur#user.login ++ ")"; true -> "" end ++ "'' est bloqué pour " ++ integer_to_list(trunc(?DUREE_BLOCAGE_SPAM / 1000)) ++ " secondes pour cause de flood."); + nouveau_message_sys("''" ++ Profile#profile.pseudo ++ if Auteur#user.login =/= [] -> " (" ++ Auteur#user.login ++ ")"; true -> "" end ++ "'' est bloqué pour " ++ integer_to_list(trunc(?DUREE_BLOCAGE_SPAM / 1000)) ++ " secondes pour cause de flood."); Auteur#user.indice_flood =:= ?INDICE_SPAM_MAX, Delta =< ?DUREE_BLOCAGE_SPAM -> {erreur, "Bloqué pour cause de flood"}; true -> @@ -471,7 +301,7 @@ nouveau_message(Mess, Auteur_id, Repond_A_ids) -> id = Id, auteur_id = Auteur#user.id, date = now(), - pseudo = Auteur#user.pseudo, + pseudo = Profile#profile.pseudo, contenu = Mess, racine_id = if Racine_id =:= undefined -> Id; true -> Racine_id end }), @@ -501,11 +331,11 @@ nouveau_message_sys(Mess) -> % Création d'un message système lié à un troll. nouveau_message_sys(Mess, Troll_id) -> - {ok, Root} = user_by_id(0), + {ok, #user{profile = Profile}} = user_by_id(0), resultat_transaction(mnesia:transaction( fun() -> Id = nouvel_id(minichat), - mnesia:write(#minichat{id=Id, auteur_id=0, date=now(), pseudo=Root#user.pseudo, contenu=Mess, troll_id=Troll_id, racine_id=Id}), + mnesia:write(#minichat{id = Id, auteur_id = 0, date = now(), pseudo = Profile#profile.pseudo, contenu = Mess, troll_id = Troll_id, racine_id = Id}), Id end )). @@ -705,7 +535,7 @@ list_ban() -> { IP#ip_table.ip, delta_date_minute(date_plus_minutes(IP#ip_table.ban, IP#ip_table.ban_duration), Now), - e(q([{U#user.pseudo, U#user.login} || U <- mnesia:table(user), U#user.last_ip =:= IP#ip_table.ip]), [{tmpdir, ?KEY_SORT_TEMP_DIR}]) + e(q([{Profile#profile.pseudo, U#user.login} || #user{profile = Profile} = U <- mnesia:table(user), U#user.last_ip =:= IP#ip_table.ip]), [{tmpdir, ?KEY_SORT_TEMP_DIR}]) } || IP <- mnesia:table(ip_table), if IP#ip_table.ban =:= undefined -> false; true -> date_plus_minutes(IP#ip_table.ban, IP#ip_table.ban_duration) > Now end