2 % Ce module gére les différents messages envoyés par le client (javascript) via AJAX.
3 % Les messages donnés ainsi que les réponses sont au format JSON.
6 -module(euphorik_protocole
).
17 -include_lib("xmerl/include/xmerl.hrl").
18 -include("../include/euphorik_bd.hrl").
19 -include("../include/euphorik_defines.hrl").
22 % Une utilisateur s'enregistre avec un tuple {Login, Password}.
23 register([{login
, Login
}, {password
, Password
}], IP
) ->
24 Can_register
= euphorik_minichat:can_register(IP
),
26 case euphorik_minichat:user_by_login(Login
) of
28 erreur("Login déjà existant");
30 User
= euphorik_minichat:nouveau_user(Login
, Password
, generer_cookie()),
31 json_reponse_login_ok(User
)
34 erreur_register_flood()
36 % Enregistrement sans {Login, Password}
38 Can_register
= euphorik_minichat:can_register(IP
),
40 User
= euphorik_minichat:nouveau_user("<nick>", generer_cookie()),
41 json_reponse_login_ok(User
);
43 erreur_register_flood()
46 erreur_register_flood() ->
47 erreur("Trop de register (flood)").
51 % Un utilisateur se logge (avec un couple {login, mot de passe})
52 login([{login
, Login
}, {password
, Password
}]) ->
53 loginUser(euphorik_minichat:user_by_login_password(Login
, Password
));
54 % Un utilisateur se logge (avec un cookie)
55 login([{cookie
, Cookie
}]) ->
56 loginUser(euphorik_minichat:user_by_cookie(Cookie
)).
58 loginUser({ok
, User
}) ->
59 euphorik_minichat:update_date_derniere_connexion(User#user
.id
),
60 json_reponse_login_ok(User
);
62 % ajoute un délais d'attente (TODO : un autre moyen plus élégant ?)
64 erreur("Erreur login")
68 % Renvoie un string() représentant un cookie en base 36. Il y a 10^32 possibillités.
71 random:seed(A1
, A2
, A3
),
72 erlang:integer_to_list(random:uniform(math:pow(10, 32)), 36).
75 % Un utilisateur se délogge.
80 % Modification du profile.
89 {nick_format
, Nick_format_str
},
90 {main_page
, Main_page
},
91 {conversations
, {array
, Conversations_json
}}
94 % est-ce que les messages auquel on répond existent ?
95 Conversations
= lists:foldr(
96 fun({struct
, [{root
, Root
}, {page
, Page
}]}, Acc
) ->
97 Message_existe
= euphorik_minichat:message_existe(Root
),
107 case euphorik_minichat:set_profile(Cookie
, Login
, Password
, Pseudo
, Email
, Css
, list_to_atom(Nick_format_str
), Main_page
, Conversations
) of
111 erreur("Login déjà pris");
113 erreur("Impossible de mettre à jour le profile")
117 % Renvoie les messages appropriés.
118 % last_message id et cookie sont facultatifs
119 % TODO : erreur : {badmatch,false}
121 Cookie
= case lists:keysearch(cookie
, 1, Data
) of {value
, {_
, C
}} -> C
; _
-> inconnu
end,
122 Last_message_id
= case lists:keysearch(last_message_id
, 1, Data
) of {value
, {_
, Id
}} -> Id
; _
-> 0 end,
123 {value
, {_
, Message_count
}} = lists:keysearch(message_count
, 1, Data
),
124 Main_page
= case lists:keysearch(main_page
, 1, Data
) of {value
, {_
, P
}} -> P
; _
-> 1 end,
125 {value
, {_
, {array
, Conversations_json
}}} = lists:keysearch(conversations
, 1, Data
),
126 Conversations
= lists:map(
127 fun({struct
, [{root
, Racine
}, {page
, Page
} | Reste
]}) ->
128 Last_mess_conv
= case Reste
of [{last_message_id
, L
}] -> L
; _
-> 0 end,
129 {Racine
, Page
, Last_mess_conv
}
133 User
= case euphorik_minichat:user_by_cookie(Cookie
) of
138 {reply
, "new_message"},
139 {conversations
, {array
,
140 % accrochez-vous ca va siouxer ;)
144 {last_page
, not Plus
},
147 fun({Mess
, Repond_a
}) ->
148 Est_proprietaire
= User
=/= inconnu andalso User#user
.id
=:= Mess#minichat
.auteur_id
,
149 A_repondu_a_message
= User
=/= inconnu andalso
euphorik_minichat:a_repondu_a_message(User#user
.id
, Mess#minichat
.id
),
150 Est_une_reponse_a_user
= User
=/= inconnu andalso
euphorik_minichat:est_une_reponse_a_user(User#user
.id
, Mess#minichat
.id
),
151 % io:format("Repond_a : ~p~n", [Repond_a]),
153 if Mess#minichat
.auteur_id
=:= 0 ->
156 {ok
, U2
} = euphorik_minichat:user_by_id(Mess#minichat
.auteur_id
),
160 {id
, Mess#minichat
.id
},
161 {date, format_date(Mess#minichat
.date)},
162 {system
, Mess#minichat
.auteur_id
=:= 0},
163 {owner
, Est_proprietaire
},
164 {answered
, A_repondu_a_message
},
165 {is_a_reply
, Est_une_reponse_a_user
},
166 {nick
, Mess#minichat
.pseudo
},
167 {login
, if User_mess
=:= inconnu
-> Mess#minichat
.pseudo
; true
-> User_mess#user
.login
end},
168 {content
, Mess#minichat
.contenu
},
169 {answer_to
, {array
, lists:map(
171 {ok
, M
} = euphorik_minichat:message_by_id(Id_mess
),
172 {ok
, User_reponse
} = euphorik_minichat:user_by_mess(M#minichat
.id
),
173 {struct
, [{id
, M#minichat
.id
}, {nick
, M#minichat
.pseudo
}, {login
, User_reponse#user
.login
}]}
184 euphorik_minichat_conversation:conversations(
195 % Un utilisateur envoie un message
201 {answer_to
, {array
, Answer_to
}}
204 case euphorik_minichat:user_by_cookie(Cookie
) of
206 Strip_content
= string:strip(Content
),
207 if (Strip_content
=:= []) ->
208 erreur("Message vide");
210 % TODO : non-atomique (update_pseudo+nouveau_message)
211 euphorik_minichat:update_pseudo_user(User#user
.id
, Nick
),
212 case euphorik_minichat:nouveau_message(Strip_content
, User#user
.id
, Answer_to
) of
213 erreur
-> erreur("Impossible d'ajouter un nouveau message");
219 erreur("Utilisateur inconnu")
223 % Construit une erreur
228 {error_message
, Message
}
233 % Formatage d'une heure
234 % local_time() -> string
236 DateLocal
= calendar:now_to_local_time(Date
),
237 DateNowLocal
= calendar:local_time(),
238 {{Annee
, Mois
, Jour
}, {Heure
, Minute
, Seconde
}} = DateLocal
,
239 {{AnneeNow
, _
, _
}, {_
, _
, _
}} = DateNowLocal
,
240 Hier
= calendar:date_to_gregorian_days(element(1, DateLocal
)) =:= calendar:date_to_gregorian_days(element(1, DateNowLocal
)) - 1,
242 if element(1, DateLocal
) =:= element(1, DateNowLocal
) ->
246 Annee
=:= AnneeNow
->
247 io_lib:format("~2.10.0B/~2.10.0B ", [Jour
, Mois
]);
249 io_lib:format("~2.10.0B/~2.10.0B/~B ", [Jour
, Mois
, Annee
])
251 io_lib:format("~2.10.0B:~2.10.0B:~2.10.0B", [Heure
, Minute
, Seconde
])
255 %%%%%%%%% <Réponses JSON> %%%%%%%%%
258 {struct
, [{reply
, "ok"}]}.
261 json_reponse_login_ok(User
) ->
265 {status
, if (User#user
.password
=/= []) and (User#user
.login
=/= []) -> "auth_registered"; true
-> "auth_not_registered" end},
266 {cookie
, User#user
.cookie
},
268 {nick
, User#user
.pseudo
},
269 {login
, User#user
.login
},
270 {email
, User#user
.email
},
271 {css
, User#user
.css
},
272 {nick_format
, atom_to_list(User#user
.nick_format
)},
273 {main_page
, User#user
.page_principale
},
280 {root
, element(1, C
)},
281 {page
, element(2, C
)}
285 User#user
.conversations
293 %%%%%%%%% </réponses JSON> %%%%%%%%%