*.iws
*.beam
-var/
\ No newline at end of file
+var/
+/BD
+/data
\ No newline at end of file
-See : http://dev.euphorik.ch/wiki/euk/Home
\ No newline at end of file
+See : https://dev.euphorik.ch/projects/euk/wiki
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<module type="ERLANG_MODULE" version="4">
- <component name="FacetManager">
- <facet type="erlang" name="Erlang">
- <configuration />
- </facet>
- </component>
- <component name="NewModuleRootManager" inherit-compiler-output="true">
- <exclude-output />
- <content url="file://$MODULE_DIR$">
- <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
- </content>
- <orderEntry type="jdk" jdkName="Erlang 17" jdkType="Erlang SDK" />
- <orderEntry type="sourceFolder" forTests="false" />
- </component>
-</module>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
- <component name="CompilerConfiguration">
- <option name="DEFAULT_COMPILER" value="Javac" />
- <resourceExtensions />
- <wildcardResourcePatterns>
- <entry name="!?*.java" />
- <entry name="!?*.form" />
- <entry name="!?*.class" />
- <entry name="!?*.groovy" />
- <entry name="!?*.scala" />
- <entry name="!?*.flex" />
- <entry name="!?*.kt" />
- <entry name="!?*.clj" />
- <entry name="!?*.aj" />
- </wildcardResourcePatterns>
- <annotationProcessing>
- <profile default="true" name="Default" enabled="false">
- <processorPath useClasspath="true" />
- </profile>
- </annotationProcessing>
- </component>
- <component name="CopyrightManager" default="" />
- <component name="DependencyValidationManager">
- <option name="SKIP_IMPORT_STATEMENTS" value="false" />
- </component>
- <component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
- <component name="IdProvider" IDEtalkID="B6AEF54337EB68A2965D2FCB524498D7" />
- <component name="ProjectModuleManager">
- <modules>
- <module fileurl="file://$PROJECT_DIR$//euphorik.iml" filepath="$PROJECT_DIR$//euphorik.iml" />
- </modules>
- </component>
- <component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true">
- <output url="file://$PROJECT_DIR$/out" />
- </component>
- <component name="VcsDirectoryMappings">
- <mapping directory="$PROJECT_DIR$" vcs="Git" />
- </component>
-</project>
\ No newline at end of file
<body>\r
<div id="container">\r
<erl>\r
- % permet de prédéfinir la "class" du logo pour un ekMaster...\r
+ % To redefine the logo class for the ekMasters.\r
out(A) ->\r
- Est_ek_master = euphorik_bd:is_ek_master_from_cookie(yaws_api:find_cookie_val("cookie", A)),\r
- {ehtml, {'div', [{id, "logo"}] ++ if Est_ek_master -> [{class, "ekMaster"}]; true -> [] end}}.\r
+ Is_ek_master = euphorik_bd:is_ek_master_from_cookie(yaws_api:find_cookie_val("cookie", A)),\r
+ {ehtml, {'div', [{id, "logo"}] ++ if Is_ek_master -> [{class, "ekMaster"}]; true -> [] end}}.\r
</erl>\r
<div id="info" style="display:none" ><div id="icone"></div><div class="close" ></div><div class="message" ></div><div class="buttons"></div></div>\r
<div id="waitbar" style="display:none" ><div class="image"></div></div>\r
<erl>\r
% parse les styles disponible\r
out(A) ->\r
- Stlyes_dir = A#arg.docroot ++ "/styles",\r
- {ok, Liste_dir} = file:list_dir(Stlyes_dir),\r
+ Styles_dir = A#arg.docroot ++ "/styles",\r
+ {ok, Liste_dir} = file:list_dir(Styles_dir),\r
{ehtml,\r
lists:foldr(\r
fun(Dir, Acc) ->\r
- case file:consult(Stlyes_dir ++ "/" ++ Dir ++ "/infos.txt") of\r
+ case file:consult(Styles_dir ++ "/" ++ Dir ++ "/infos.txt") of\r
{ok, [{nom, Nom}]} ->\r
[{option, [{value, Dir}], Nom} | Acc];\r
_ ->\r
// le main
$(document).ready(
- function() {
+ function() {
var fragment = new Fragment();
var formatter = new euphorik.Formatter();
var util = new euphorik.Util(formatter);
);
var client = new euphorik.Client(util, communication);
var pages = new euphorik.Pages(fragment, communication);
-
+
// Client authentification with the cookie information (if it exists).
client.connectionCookie();
-
+
$("#menuCss").change(function() { client.setCss("styles/" + $("option:selected", this).attr("value") + "/euphorik.css"); });
- // FIXME : doesn't work under Opera
- // see : http://dev.jquery.com/ticket/2892#preview
$(window).unload(function() { client.flush(); });
-
+
$("#menu .minichat").click(function() { pages.displayPage("minichat"); });
$("#menu .admin").click(function() { pages.displayPage("admin"); });
$("#menu .profile").click(function() { pages.displayPage("profile"); });
});
$("#menu .register").click(function(){ pages.displayPage("register"); });
$("#menu .about").click(function(){ pages.displayPage("about"); });
-
+
// TODO : simplification : such link[1] should be created and automatically open the right page without
// explicitly add a page.
// [1] : <a class="pageLink" href="termes_of_use">Terms of use</a>
$("#footer .termsOfUse").click(function(){ pages.displayPage("terms_of_use"); });
-
+
pages.addPage(new euphorik.PageMinichat(client, formatter, util, communication), true);
pages.addPage(new euphorik.PageAdmin(client, formatter, util, communication));
pages.addPage(new euphorik.PageProfile(client, formatter, util));
pages.addPage(new euphorik.PageRegister(client, formatter, util));
pages.addPage(new euphorik.PageAbout(client, formatter, util, communication));
pages.addPage("terms_of_use");
-
+
pages.displayPage(); // display the default page
}
);
% You should have received a copy of the GNU General Public License\r
% along with Euphorik. If not, see <http://www.gnu.org/licenses/>.\r
%\r
-% Module mettant à disposition tout un tas de fonction pour l'administration de la base de données euphorik comme :\r
-% - Création de la BD\r
-% - Mise à jour de la BD\r
-% - Backup et restauration\r
-% - Copie de la BD à partir d'un autre noeud\r
-\r
+% Some functions to manage the database like creating, updating, backuping etc.\r
+%\r
+% @author G.Burri\r
\r
-module(euphorik_bd_admin).\r
-author("Greg Burri <greg.burri@gmail.com>").\r
print_users/1,\r
print_user/1\r
]).\r
+\r
-import(qlc, [e/2, q/1, cursor/2]).\r
+\r
-include("../include/euphorik_bd.hrl").\r
-include("../include/euphorik_defines.hrl").\r
-include_lib("stdlib/include/qlc.hrl").\r
\r
-\r
-% Renvoie la version courante de la BD.\r
+% Return the current version of the DB.\r
version_bd() ->\r
euphorik_bd:resultat_transaction(mnesia:transaction(\r
fun() ->\r
end\r
)).\r
\r
-\r
-% Instructions pour créer une nouvelle base :\r
-% $erl -sname yaws -mnesia dir '"/projets/euphorik/BD"'\r
-% voir doc/installation.txt\r
-% >l(euphorik_bd).\r
-% >euphorik_bd:create().\r
+% Create a the database. Warning: it will delete all existent data.\r
+% Example:\r
+% $erl -sname yaws -mnesia dir '"/projects/euphorik/DB"'\r
+% >l(euphorik_admin).\r
+% >euphorik_bd:create().\r
create() ->\r
mnesia:stop(),\r
mnesia:delete_schema([node()]),\r
{attributes, record_info(fields, troll)},\r
{disc_copies, [node()]}\r
]),\r
- creer_indexes().\r
+ create_indexes().\r
\r
-\r
-% mis à part car lors de la reprise de données avec load_textfile les indexes ne sont pas recréés\r
-creer_indexes() ->\r
- % commence par supprimer les anciens indexes\r
+% Create all the needed indexes on the tables.\r
+create_indexes() ->\r
+ % Delete all existing indexes.\r
lists:foreach(fun(T) ->\r
lists:foreach(fun(P) ->\r
mnesia:del_table_index(T, P)\r
mnesia:add_table_index(troll, date_post),\r
mnesia:add_table_index(troll, id_minichat).\r
\r
-\r
-% Connexion à la base de données de yaws sur overnux\r
+% To connect to an remote database node.\r
connect() ->\r
- connect(yaws@flynux).\r
+ connect(yaws@x220).\r
connect(Node) ->\r
mnesia:start(),\r
mnesia:change_config(extra_db_nodes, [Node]).\r
\r
-\r
-% Efface toutes les données de la base de données.\r
+% Remove all data.\r
reset() ->\r
mnesia:clear_table(counter),\r
mnesia:clear_table(proprietes),\r
mnesia:clear_table(minichat),\r
mnesia:clear_table(troll),\r
mnesia:clear_table(ip_table),\r
- % crée l'utilisateur root\r
+ % Create the root user.\r
mnesia:transaction(fun() ->\r
- mnesia:write(#proprietes{nom = version, valeur = ?VERSION_BD}),\r
+ mnesia:write(#proprietes{nom = version, valeur = ?DB_VERSION}),\r
User = #user{id = 0, profile = #profile{pseudo = "Sys"}, login = "Sys", date_creation = erlang:timestamp(), date_derniere_connexion = erlang:timestamp(), ek_master = true},\r
mnesia:write(User),\r
User\r
end),\r
- peupler_texte().\r
-\r
+ populate_text().\r
\r
-peupler_texte() ->\r
+populate_text() ->\r
mnesia:transaction(fun() ->\r
mnesia:write(#texte{ id = 10, fr = "Login déjà existant"}),\r
mnesia:write(#texte{ id = 20, fr = "Trop de register (flood)"}),\r
mnesia:write(#texte{ id = 70, fr = "Page inconnue"}),\r
mnesia:write(#texte{ id = 80, fr = "Vous êtes banni pour encore ~s"}),\r
mnesia:write(#texte{ id = 90, fr = "Message vide"}),\r
- mnesia:write(#texte{ id = 100, fr = "Impossible d'ajouter un nouveau message. Raison : ~s"}),\r
+ mnesia:write(#texte{ id = 100, fr = "Impossible d'ajouter un nouveau message. Cause : ~s"}),\r
mnesia:write(#texte{ id = 110, fr = "Utilisateur inconnu"}),\r
mnesia:write(#texte{ id = 120, fr = "Il n'est pas possible de s'auto bannir"}),\r
mnesia:write(#texte{ id = 130, fr = "L'utilisateur est lui même un ekMaster"}),\r
mnesia:write(#texte{ id = 230, fr = "Seul les ekMaster peuvent connaitre la liste des ips bannies"})\r
end).\r
\r
-\r
-% Met à jour la bd, compare ?VERSION_BD avec la version dans la table 'proprietes'\r
-% et exécute les patchs nécessaires.\r
+% Update the database to the latest version (?DB_VERSION).\r
update() ->\r
case mnesia:dirty_read({proprietes, version}) of\r
[#proprietes{valeur = Version}] ->\r
update(Version);\r
_ ->\r
- erreur\r
+ error\r
end.\r
-\r
-\r
-% Mise à jour de la BD.\r
-% attention : il est nécessaire de se trouver dans une transaction.\r
-update(?VERSION_BD) -> fini;\r
+update(?DB_VERSION) -> finished;\r
update(Version) ->\r
- case mnesia:backup(fichier_backup(Version)) of\r
+ case mnesia:backup(backup_file_path(Version)) of\r
ok ->\r
case patch(Version) of\r
ok ->\r
mnesia:dirty_write(#proprietes{nom = version, valeur = Version + 1}),\r
update(Version + 1);\r
- Erreur ->\r
- Erreur\r
+ Error ->\r
+ Error\r
end;\r
- {error, Raison} -> {error, lists:flatten(io_lib:format("Erreur de création du backup de la version ~w : ~w", [Version, Raison]))}\r
+ {error, Message} -> {error, lists:flatten(io_lib:format("Error: unable to create a backup file prior updating the database to the version ~w: ~w", [Version, Message]))}\r
end.\r
\r
\r
{attributes, record_info(fields, texte)},\r
{disc_copies, [node()]}\r
]),\r
- peupler_texte(),\r
+ populate_text(),\r
% traitement des users\r
mnesia:transform_table(\r
user,\r
lists:foreach(fun(M) -> Traiter_message(M, M#minichat.id) end, Messages)\r
end\r
) of\r
- {aborted, Raison} -> {erreur, Raison};\r
+ {aborted, Cause} -> {error, Cause};\r
{atomic, _} -> ok\r
end;\r
% 2 -> 3\r
% la table troll utilise maintenant son index et pas celui de la table minichat (correction d'un vieux bug)\r
mnesia:write(#counter{key = troll, value = mnesia:table_info(minichat, size)})\r
end),\r
- creer_indexes(). % uniquement pour l'indice sur id_minichat de la table troll\r
+ create_indexes(). % uniquement pour l'indice sur id_minichat de la table troll\r
\r
\r
% Renvoie le dossier dans lequel les backups sont effectué, ce dossier doit être en écriture.\r
\r
\r
% Renvoie le fichier (avec le chemin) correspondant à la version Version, par exemple : "/var/euphorik/BD/backups/backup1"\r
-fichier_backup(Version) when is_integer(Version) ->\r
+backup_file_path(Version) when is_integer(Version) ->\r
dossier_backups() ++ "backup" ++ integer_to_list(Version).\r
\r
\r
% Reviens à une version précédente de la base de données.\r
% (les données insérées durant les versions plus récentes sont perdues).\r
restore(Version) when is_integer(Version) ->\r
- mnesia:restore(fichier_backup(Version), []). % [{default_op, recreate_tables}]).\r
+ mnesia:restore(backup_file_path(Version), []). % [{default_op, recreate_tables}]).\r
\r
\r
% Change le nom du noeud d'un backup.\r
end,\r
mnesia:traverse_backup(Source, Target, Convert, switched).\r
\r
-\r
-% Obsolète\r
-%~ backup_text(File) ->\r
- %~ mnesia:dump_to_textfile(File).\r
-%~ restore_text(File) ->\r
- %~ mnesia:stop(),\r
- %~ mnesia:delete_schema([node()]),\r
- %~ mnesia:start(),\r
- %~ create_tables(),\r
- %~ case mnesia:load_textfile(File) of\r
- %~ {atomic, ok} ->\r
- %~ update(),\r
- %~ creer_indexes();\r
- %~ Erreur ->\r
- %~ Erreur\r
- %~ end.\r
-\r
-\r
toggle_ek_master(User_id) ->\r
euphorik_bd:resultat_transaction(mnesia:transaction(\r
fun() ->\r
case Users of\r
[User] ->\r
mnesia:write(User#user{ek_master = not User#user.ek_master});\r
- _ -> erreur\r
+ _ -> error\r
end\r
end\r
)).\r
{ok, User} ->\r
print_user(User);\r
_ ->\r
- {erreur, "Login pas trouvé : " ++ Login}\r
+ {error, "Login pas trouvé : " ++ Login}\r
end;\r
% Affichage d'un user en fonction de son id\r
print_user(Id) when is_integer(Id) ->\r
{ok, User} ->\r
print_user(User);\r
_ ->\r
- {erreur, "Id pas trouvé : " ++ integer_to_list(Id)}\r
+ {error, "Id pas trouvé : " ++ integer_to_list(Id)}\r
end.\r
\r
end.
-% Retourne la difference entre deux timestamp (erlang:now()) en miliseconde
+% Retourne la difference entre deux timestamp (erlang:timestamp()) en miliseconde
delta_date_ms(D1, D2) ->
1000000000 * abs(element(1, D1) - element(1, D2)) + 1000 * abs(element(2, D1) - element(2, D2)) + trunc(abs(element(3, D1) - element(3, D2)) / 1000).
%\r
% @author GBurri\r
\r
-\r
% Version de la BD\r
--define(VERSION_BD, 3).\r
+-define(DB_VERSION, 3).\r
-define(TABLES, [counter, proprietes, minichat, reponse_minichat, user, ip_table, troll]).\r
\r
-\r
% Pour générer des id\r
-record(counter,\r
{\r
value\r
}).\r
\r
-\r
% Mémorse toutes les propriétés, entre autre la version des données\r
-record(proprietes,\r
{\r
valeur\r
}).\r
\r
-\r
% Contient tous les textes que peut envoyer le serveur vers client.\r
-record(texte,\r
{\r
fr\r
}).\r
\r
-\r
% décrit un enregistrement d'un message\r
-record(minichat,\r
{\r
id, % integer\r
auteur_id, % -> #user.id\r
- date, % erlang:now()\r
+ date, % erlang:timestamp()\r
pseudo, % chaine de caractère\r
contenu, % chaine de caractère\r
racine_id = undefined, % la racine, par défaut correspond à l'id du message\r
status = normal % can be equal to normal, censored or deleted\r
}).\r
\r
-\r
% type bag\r
% 'repondant' repond à 'cible'\r
-record(reponse_minichat,\r
cible % -> #minichat.id\r
}).\r
\r
-\r
--record(profile, % attention : pas une table !\r
+% Warning: this is not a table, it's part of the user table.\r
+-record(profile,\r
{\r
pseudo = [], % string()\r
email = [], % string()\r
conversations = [] % [{integer(), bool}], la liste des messages correspondant au conversation {racine, reduite?}\r
}).\r
\r
-\r
-record(user,\r
{\r
id,\r
login = [], % string()\r
password = [], % string() (md5)\r
profile = #profile{},\r
- date_creation, % erlang:now()\r
- date_derniere_connexion, % erlang:now(), est mis à jour lors de n'importe quelle activitée (envoie de message par exemple)\r
+ date_creation, % erlang:timestamp()\r
+ date_derniere_connexion, % erlang:timestamp(), est mis à jour lors de n'importe quelle activitée (envoie de message par exemple)\r
indice_flood = 0, % integer() est incrémenté lorsque l'utilisateur envoie trop rapidement des messages.\r
ek_master = false,\r
last_ip = undefined % integer(), undefined si inconnu\r
}).\r
\r
-\r
% identificateur : (ip)\r
-record(ip_table,\r
{\r
date_last_try_login % pour l'instant pas utilisé\r
}).\r
\r
-\r
-record(troll,\r
{\r
id,\r
id_user,\r
id_minichat = undefined, % l'id du message associé\r
- date_create, % erlang:now()\r
- date_post = undefined, % date à laquelle le troll est affiché sur la page principale. undefined initialement puis erlang:now() quand affiché\r
+ date_create, % erlang:timestamp()\r
+ date_post = undefined, % date à laquelle le troll est affiché sur la page principale. undefined initialement puis erlang:timestamp() quand affiché\r
content % chaine de caractère\r
}).\r
% le premier argument est le nom du noeud est peut valoir :
% - yaws : noeud de production
% - yaws_dev : noeud de pre-production
-main([Nom_node]) when Nom_node =:= "yaws"; Nom_node =:= "yaws_dev" ->
+main([Nom_node]) when Nom_node =:= "yaws"; Nom_node =:= "yaws_dev" ->
Node = list_to_atom(Nom_node ++ atom_to_list(hote())),
net_kernel:start([flynux, shortnames]),
io:format("rechargement des modules..~n"),
rpc:call(Node, mnesia, restore, [Fichier2, [{default_op, recreate_tables}]]),
rpc:call(yaws@overnux, file, delete, [Fichier]),
rpc:call(Node, file, delete, [Fichier2]).
-
\ No newline at end of file