From: Ummon Date: Sun, 14 Apr 2019 10:44:28 +0000 (+0200) Subject: Use the new json2 module (from yaws) X-Git-Tag: 1.1.7~1 X-Git-Url: http://git.euphorik.ch/?a=commitdiff_plain;h=79f0cfc91b7220d98e4caf50fbb3857807fc6bc4;p=euphorik.git Use the new json2 module (from yaws) --- diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..20b5334 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +BD/ +ebin/ \ No newline at end of file diff --git a/js/comet.js b/js/comet.js index 8c427c9..976c5fc 100644 --- a/js/comet.js +++ b/js/comet.js @@ -46,10 +46,10 @@ Comet = function(page, version) { this.page = page; this.version = version; - + // l'objet JSONHttpRequest représentant la connexion d'attente this.attenteCourante = undefined; - + // le multhreading du pauvre, merci javascript de m'offrire autant de primitives pour la gestion de la concurrence... this.stop = false; }; @@ -59,14 +59,14 @@ Comet = function(page, version) { */ Comet.prototype.stopAttenteCourante = function() { this.stop = true; - + if (this.attenteCourante) { this.attenteCourante.abort(); } }; /** - * Attend un événement lié à la page. Non-bloquant. + * Attend un événement lié à la page. Non-bloquant. * @funSend une fonction renvoyant les données json à envoyer * @funsReceive est un objet comprenant les fonctions à appeler en fonction du "reply" * les fonctions acceptent un paramètre correspondant au données reçues. @@ -74,11 +74,11 @@ Comet.prototype.stopAttenteCourante = function() { */ Comet.prototype.waitEvent = function(funSend, funsReceive) { this.stopAttenteCourante(); - + this.stop = false; - + var thisComet = this; - + // on doit conserver l'ordre des valeurs de l'objet JSON (le serveur les veut dans l'ordre définit dans le protocole) // TODO : ya pas mieux ? var dataToSend = { @@ -89,7 +89,7 @@ Comet.prototype.waitEvent = function(funSend, funsReceive) { objectEach(poulpe, function(k, v) { dataToSend[k] = v; }); - + this.attenteCourante = jQuery.ajax({ type: "POST", url: "request", @@ -100,13 +100,13 @@ Comet.prototype.waitEvent = function(funSend, funsReceive) { success: function(data) { funsReceive[data.reply](data); - + // rappel de la fonction dans 100 ms setTimeout(function(){ thisComet.waitEvent2(funSend, funsReceive); }, 100); }, error: function(XMLHttpRequest, textStatus, errorThrown) { - ;; console.log("Connexion perdue dans Comet.prototype.waitEvent() : \n" + textStatus); + // console.log("Connexion perdue dans Comet.prototype.waitEvent() : \n" + textStatus); setTimeout(function(){ thisComet.waitEvent2(funSend, funsReceive); }, 1000); } }); @@ -120,4 +120,4 @@ Comet.prototype.waitEvent2 = function(funSend, funsReceive) { return; } this.waitEvent(funSend, funsReceive); -}; \ No newline at end of file +}; diff --git a/js/communication.js b/js/communication.js index 985aeed..3f44227 100644 --- a/js/communication.js +++ b/js/communication.js @@ -19,42 +19,42 @@ // Regroupe la partie communication JSON client -> serveur de euphorik. // Voir : http://dev.euphorik.ch/wiki/euk/Protocole -/** - * Les fonctions debutReq et finReq servent, par exemple, à afficher à l'utilisateur +/** + * Les fonctions debutReq et finReq servent, par exemple, à afficher à l'utilisateur * qu'une communication est en cours. - * @param funError un fonction executée lors d'un réponse 'error' de la part du serveur, peut être redéfinit pour une requête. - * @param funDebutReq fonction appelée au début d'une requête (facultatif) + * @param funError un fonction executée lors d'un réponse 'error' de la part du serveur, peut être redéfinit pour une requête. + * @param funDebutReq fonction appelée au début d'une requête (facultatif) * @param funFinReq fonction appelée à la fin d'une requête (facultatif) */ euphorik.Communication = function(funError, funDebutReq, funFinReq) { - this.funError = funError; - this.funDebutReq = funDebutReq; + this.funError = funError; + this.funDebutReq = funDebutReq; this.funFinReq = funFinReq; -}; - -/** - * Charge un fichier depuis une url et retourne son contenu. - */ -euphorik.Communication.prototype.load = function(url) { - if (this.funDebutReq) { - this.funDebutReq(); - } - var contenu = ""; - $.ajax({async: false, url: url, success : function(page) { contenu += page; }}); - if (this.funFinReq) { - this.funFinReq(); - } - return contenu; }; - -/** - * Effectue une requête JSON auprès du serveur. - * @param action une chaine spécifiant l'action, par exemple "put_message" - * @param json les données à envoyer associé à l'action, par exemple {"cookie" : "LKJDLAKSJBFLKASN", "nick" : "Paul", "content" : "Bonjour", "answer_to" : [] } - * @param funOk la fonction exécuté après réception des données du serveur - * @param funError la fonction exécuté si une erreur arrive (facultatif) - * @param asynchrone true pour une communication asychrone (facultatif, truepar défaut) - * @param paramsSupp un objet contenant des paramètres supplémentaire pour la fonction ajax de jQuery (facultatif) + +/** + * Charge un fichier depuis une url et retourne son contenu. + */ +euphorik.Communication.prototype.load = function(url) { + if (this.funDebutReq) { + this.funDebutReq(); + } + var contenu = ""; + $.ajax({async: false, url: url, success : function(page) { contenu += page; }}); + if (this.funFinReq) { + this.funFinReq(); + } + return contenu; +}; + +/** + * Effectue une requête JSON auprès du serveur. + * @param action une chaine spécifiant l'action, par exemple "put_message" + * @param json les données à envoyer associé à l'action, par exemple {"cookie" : "LKJDLAKSJBFLKASN", "nick" : "Paul", "content" : "Bonjour", "answer_to" : [] } + * @param funOk la fonction exécuté après réception des données du serveur + * @param funError la fonction exécuté si une erreur arrive (facultatif) + * @param asynchrone true pour une communication asychrone (facultatif, truepar défaut) + * @param paramsSupp un objet contenant des paramètres supplémentaire pour la fonction ajax de jQuery (facultatif) */ euphorik.Communication.prototype.requete = function(action, json, funOk, funError, asynchrone, paramsSupp) { var thisCommunication = this; @@ -65,12 +65,12 @@ euphorik.Communication.prototype.requete = function(action, json, funOk, funErro var mess = this.getBase(action); objectEach(json, function(nom, val) { mess[nom] = val; - }); - - if (this.funDebutReq) { - this.funDebutReq(); + }); + + if (this.funDebutReq) { + this.funDebutReq(); } - + paramsAjax = { async: asynchrone, type: "POST", @@ -78,9 +78,9 @@ euphorik.Communication.prototype.requete = function(action, json, funOk, funErro dataType: "json", data: { action : JSON.stringify(mess) }, success: - function(data) { - if (thisCommunication.funFinReq) { - thisCommunication.funFinReq(); + function(data) { + if (thisCommunication.funFinReq) { + thisCommunication.funFinReq(); } if (data.reply === "error") { if (funError) { @@ -91,21 +91,21 @@ euphorik.Communication.prototype.requete = function(action, json, funOk, funErro } else if (funOk) { funOk(data); } - }, - error: - function(data) { - if (thisCommunication.funFinReq) { - thisCommunication.funFinReq(); - } + }, + error: + function(data) { + if (thisCommunication.funFinReq) { + thisCommunication.funFinReq(); + } } }; - + if (paramsSupp) { objectEach(paramsSupp, function(nom, val) { paramsAjax[nom] = val; }); } - + jQuery.ajax(paramsAjax); }; @@ -113,4 +113,4 @@ euphorik.Communication.prototype.getBase = function(action) { return { "header" : { "action" : action, "version" : euphorik.conf.versionProtocole } }; -}; \ No newline at end of file +}; diff --git a/js/conf.js b/js/conf.js index 6ab068b..8360e4f 100644 --- a/js/conf.js +++ b/js/conf.js @@ -26,8 +26,8 @@ euphorik.conf = { tempsAffichageMessageDialogue : 4000, // en ms tempsKick : 15, // en minute tempsBan : 60 * 24 * 3, // en minutes (3 jours) - smiles : { - "smile" : [/:\)/g, /:-\)/g], + smiles : { + "smile" : [/:\)/g, /:-\)/g], "bigsmile" : [/:D/g, /:-D/g], "clin" : [/;\)/g, /;-\)/g], "cool" : [/8\)/g, /8-\)/g], diff --git a/js/fragment.js b/js/fragment.js index 4ffbf8f..50ec943 100644 --- a/js/fragment.js +++ b/js/fragment.js @@ -72,4 +72,4 @@ Fragment.prototype.write = function() { first = false; }); window.location.hash = fragmentsStr; -}; \ No newline at end of file +}; diff --git a/js/libs/jquery.lightbox.js b/js/libs/jquery.lightbox.js index 41c425f..528a30b 100644 --- a/js/libs/jquery.lightbox.js +++ b/js/libs/jquery.lightbox.js @@ -42,7 +42,7 @@ keyToClose: 'c', // (string) (c = close) Letter to close the jQuery lightBox interface. Beyond this letter, the letter X and the SCAPE key is used to. keyToPrev: 'p', // (string) (p = previous) Letter to show the previous image keyToNext: 'n', // (string) (n = next) Letter to show the next image. - // Don´t alter these variables in any way + // Don�t alter these variables in any way imageArray: [], activeImage: 0 },settings); @@ -72,11 +72,11 @@ settings.imageArray.length = 0; // Unset image active information settings.activeImage = 0; - // We have an image set? Or just an image? Let´s see it. + // We have an image set? Or just an image? Let�s see it. if ( jQueryMatchedObj.length == 1 ) { settings.imageArray.push(new Array(objClicked.getAttribute('href'),objClicked.getAttribute('title'))); } else { - // Add an Array (as many as we have), with href and title atributes, inside the Array that storage the images references + // Add an Array (as many as we have), with href and title atributes, inside the Array that storage the images references for ( var i = 0; i < jQueryMatchedObj.length; i++ ) { settings.imageArray.push(new Array(jQueryMatchedObj[i].getAttribute('href'),jQueryMatchedObj[i].getAttribute('title'))); } @@ -125,7 +125,7 @@ */ function _set_interface() { // Apply the HTML markup into body tag - $('body').append('
'); + $('body').append('
'); // Get page sizes var arrPageSizes = ___getPageSize(); // Style overlay and show it @@ -144,7 +144,7 @@ }).show(); // Assigning click events in elements to close overlay $('#jquery-overlay,#jquery-lightbox').click(function() { - _finish(); + _finish(); }); // Assign the _finish function to lightbox-loading-link and lightbox-secNav-btnClose objects $('#lightbox-loading-link,#lightbox-secNav-btnClose').click(function() { @@ -170,7 +170,7 @@ }); } /** - * Prepares image exibition; doing a image´s preloader to calculate it´s size + * Prepares image exibition; doing a image�s preloader to calculate it�s size * */ function _set_image_to_view() { // show the loading @@ -196,16 +196,16 @@ /** * Perfomance an effect in the image container resizing it * - * @param integer intImageWidth The image´s width that will be showed - * @param integer intImageHeight The image´s height that will be showed + * @param integer intImageWidth The image�s width that will be showed + * @param integer intImageHeight The image�s height that will be showed */ function _resize_container_image_box(intImageWidth,intImageHeight) { // Get current width and height var intCurrentWidth = $('#lightbox-container-image-box').width(); var intCurrentHeight = $('#lightbox-container-image-box').height(); // Get the width and height of the selected image plus the padding - var intWidth = (intImageWidth + (settings.containerBorderSize * 2)); // Plus the image´s width and the left and right padding value - var intHeight = (intImageHeight + (settings.containerBorderSize * 2)); // Plus the image´s height and the left and right padding value + var intWidth = (intImageWidth + (settings.containerBorderSize * 2)); // Plus the image�s width and the left and right padding value + var intHeight = (intImageHeight + (settings.containerBorderSize * 2)); // Plus the image�s height and the left and right padding value // Diferences var intDiffW = intCurrentWidth - intWidth; var intDiffH = intCurrentHeight - intHeight; @@ -215,9 +215,9 @@ if ( $.browser.msie ) { ___pause(250); } else { - ___pause(100); + ___pause(100); } - } + } $('#lightbox-container-image-data-box').css({ width: intImageWidth }); $('#lightbox-nav-btnPrev,#lightbox-nav-btnNext').css({ height: intImageHeight + (settings.containerBorderSize * 2) }); }; @@ -246,7 +246,7 @@ // If we have a image set, display 'Image X of X' if ( settings.imageArray.length > 1 ) { $('#lightbox-image-details-currentNumber').html(settings.txtImage + ' ' + ( settings.activeImage + 1 ) + ' ' + settings.txtOf + ' ' + settings.imageArray.length).show(); - } + } } /** * Display the button navigations @@ -255,9 +255,9 @@ function _set_navigation() { $('#lightbox-nav').show(); - // Instead to define this configuration in CSS file, we define here. And it´s need to IE. Just. + // Instead to define this configuration in CSS file, we define here. And it�s need to IE. Just. $('#lightbox-nav-btnPrev,#lightbox-nav-btnNext').css({ 'background' : 'transparent url(' + settings.imageBlank + ') no-repeat' }); - + // Show the prev button, if not the first image in set if ( settings.activeImage != 0 ) { if ( settings.fixedNavigation ) { @@ -281,7 +281,7 @@ }); } } - + // Show the next button, if not the last image in set if ( settings.activeImage != ( settings.imageArray.length -1 ) ) { if ( settings.fixedNavigation ) { @@ -346,7 +346,7 @@ } // Verify the key to show the previous image if ( ( key == settings.keyToPrev ) || ( keycode == 37 ) ) { - // If we´re not showing the first image, call the previous + // If we�re not showing the first image, call the previous if ( settings.activeImage != 0 ) { settings.activeImage = settings.activeImage - 1; _set_image_to_view(); @@ -355,7 +355,7 @@ } // Verify the key to show the next image if ( ( key == settings.keyToNext ) || ( keycode == 39 ) ) { - // If we´re not showing the last image, call the next + // If we�re not showing the last image, call the next if ( settings.activeImage != ( settings.imageArray.length - 1 ) ) { settings.activeImage = settings.activeImage + 1; _set_image_to_view(); @@ -395,7 +395,7 @@ */ function ___getPageSize() { var xScroll, yScroll; - if (window.innerHeight && window.scrollMaxY) { + if (window.innerHeight && window.scrollMaxY) { xScroll = window.innerWidth + window.scrollMaxX; yScroll = window.innerHeight + window.scrollMaxY; } else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac @@ -408,7 +408,7 @@ var windowWidth, windowHeight; if (self.innerHeight) { // all except Explorer if(document.documentElement.clientWidth){ - windowWidth = document.documentElement.clientWidth; + windowWidth = document.documentElement.clientWidth; } else { windowWidth = self.innerWidth; } @@ -419,16 +419,16 @@ } else if (document.body) { // other Explorers windowWidth = document.body.clientWidth; windowHeight = document.body.clientHeight; - } + } // for small pages with total height less then height of the viewport if(yScroll < windowHeight){ pageHeight = windowHeight; - } else { + } else { pageHeight = yScroll; } // for small pages with total width less then width of the viewport - if(xScroll < windowWidth){ - pageWidth = xScroll; + if(xScroll < windowWidth){ + pageWidth = xScroll; } else { pageWidth = windowWidth; } @@ -451,7 +451,7 @@ xScroll = document.documentElement.scrollLeft; } else if (document.body) {// all other Explorers yScroll = document.body.scrollTop; - xScroll = document.body.scrollLeft; + xScroll = document.body.scrollLeft; } arrayPageScroll = new Array(xScroll,yScroll); return arrayPageScroll; @@ -461,7 +461,7 @@ * */ function ___pause(ms) { - var date = new Date(); + var date = new Date(); curDate = null; do { var curDate = new Date(); } while ( curDate - date < ms); @@ -469,4 +469,4 @@ // Return the jQuery object for chaining. The unbind method is used to avoid click conflict when the plugin is called more than once return this.unbind('click').click(_initialize); }; -})(jQuery); // Call and execute the function immediately passing the jQuery object \ No newline at end of file +})(jQuery); // Call and execute the function immediately passing the jQuery object diff --git a/js/util.js b/js/util.js index 7ba8e60..fed2106 100644 --- a/js/util.js +++ b/js/util.js @@ -29,9 +29,9 @@ euphorik.Util = function (formateur) { $("#info .fermer").click(function() { $("#info").slideUp(50); }); - + $("body").append('
').append('

'); - + this.formateur = formateur; this.bulleActive = true; }; @@ -43,9 +43,9 @@ euphorik.Util.messageType = {informatif: 0, question: 1, erreur: 2}; * @param message le message (string) * @param type voir 'messageType'. par défaut messageType.informatif * @param les boutons sous la forme d'un objet ou les clefs sont les labels des boutons - * et les valeurs les fonctions executées lorsqu'un bouton est activé. - * Lorsqu'un bouton est activé le message se ferme. - * @param formate faut-il formaté le message ? true par défaut + * et les valeurs les fonctions executées lorsqu'un bouton est activé. + * Lorsqu'un bouton est activé le message se ferme. + * @param formate faut-il formaté le message ? true par défaut * @param temps le temps d'affichage du message en seconde, -1 pour une durée infinie */ euphorik.Util.prototype.messageDialogue = function(message, type, boutons, formate, temps) { @@ -57,26 +57,26 @@ euphorik.Util.prototype.messageDialogue = function(message, type, boutons, forma if (this.timeoutMessageDialogue) { clearTimeout(this.timeoutMessageDialogue); } - + var fermer = function() { $("#info").slideUp(100); }; fermer(); $("#info .message").html(!thisUtil.formateur || !formate ? message : thisUtil.formateur.traitementComplet(message)); - + switch(type) { case euphorik.Util.messageType.informatif : $("#info #icone").attr("class", "information"); break; case euphorik.Util.messageType.question : $("#info #icone").attr("class", "interrogation"); break; case euphorik.Util.messageType.erreur : $("#info #icone").attr("class", "exclamation"); break; } - + $("#info .boutons").html(""); objectEach(boutons, function(nom, bouton) { $("#info .boutons").append("
" + nom + "
").find("div:last").click(bouton).click(fermer); }); - - $("#info").slideDown(200); + + $("#info").slideDown(200); if (temps !== -1) { - this.timeoutMessageDialogue = setTimeout(fermer, temps || euphorik.conf.tempsAffichageMessageDialogue); + this.timeoutMessageDialogue = setTimeout(fermer, temps || euphorik.conf.tempsAffichageMessageDialogue); } }; @@ -95,38 +95,38 @@ euphorik.Util.prototype.afficherBoite = function(boite, cible, positionX, positi var positionCible = cible.offset(); var positionBoite = { left : positionX === euphorik.Util.positionTypeX.gauche ? positionCible.left - boite.width() : - (positionX === euphorik.Util.positionTypeX.gaucheRecouvrement ? positionCible.left - boite.width() + cible.width() : + (positionX === euphorik.Util.positionTypeX.gaucheRecouvrement ? positionCible.left - boite.width() + cible.width() : (positionX === euphorik.Util.positionTypeX.droitelsRecouvrement ? positionCible.left : (positionX === euphorik.Util.positionTypeX.droite ? positionCible.left + cible.width() : positionCible.left + cible.width() / 2 - boite.width() / 2 ))), // centre top : positionY === euphorik.Util.positionTypeY.haut ? positionCible.top - boite.height() : - (positionY === euphorik.Util.positionTypeY.hautRecouvrement ? positionCible.top - boite.height() + cible.height() : + (positionY === euphorik.Util.positionTypeY.hautRecouvrement ? positionCible.top - boite.height() + cible.height() : (positionY === euphorik.Util.positionTypeY.basRecouvrement ? positionCible.top : (positionY === euphorik.Util.positionTypeY.bas ? positionCible.top + cible.height() : positionCible.top + cible.height() / 2 - boite.height() / 2 ))) // centre }; - + // calcul les décalages en x et en y pour éviter que la boite ne sorte de la fenêtre, tient compte de la position des barres de défilement - var marge = 10; + var marge = 10; positionBoite.left = positionBoite.left < marge + window.pageXOffset ? marge + window.pageXOffset : (boite.width() - $(window).width() + (positionBoite.left - window.pageXOffset) + marge > 0 ? $(window).width() - boite.width() - marge + window.pageXOffset : positionBoite.left); positionBoite.top = positionBoite.top < marge + window.pageYOffset ? marge + window.pageYOffset : (boite.height() - $(window).height() + (positionBoite.top - window.pageYOffset) + marge > 0 ? $(window).height() - boite.height() - marge + window.pageYOffset : positionBoite.top); - + boite.css("top", positionBoite.top).css("left", positionBoite.left).show(); }; euphorik.Util.positionBulleType = {haut : 0, droite : 1, bas : 2, gauche : 3}; - -/** - * Affiche ou cache la barre d'attente. - */ -euphorik.Util.prototype.showWaitBar = function() { - $("#waitbar").show(); -}; -euphorik.Util.prototype.hideWaitBar = function() { - $("#waitbar").hide(); -}; + +/** + * Affiche ou cache la barre d'attente. + */ +euphorik.Util.prototype.showWaitBar = function() { + $("#waitbar").show(); +}; +euphorik.Util.prototype.hideWaitBar = function() { + $("#waitbar").hide(); +}; /** * Affiche un info bulle lorsque le curseur survole l'élément donné. @@ -136,11 +136,11 @@ euphorik.Util.prototype.hideWaitBar = function() { */ euphorik.Util.prototype.infoBulle = function(message, element, position) { var thisUtil = this; - var cacherBulle = function() { + var cacherBulle = function() { $("#flecheBulle").hide(); $("#messageBulle").hide(); }; - + position = position || euphorik.Util.positionBulleType.haut; element.hover( @@ -152,16 +152,16 @@ euphorik.Util.prototype.infoBulle = function(message, element, position) { var m = $("#messageBulle"); var f = $("#flecheBulle"); f.removeClass().addClass(position === euphorik.Util.positionBulleType.haut ? "flecheBulleHaut" : - (position === euphorik.Util.positionBulleType.droite ? "flecheBulleDroite" : + (position === euphorik.Util.positionBulleType.droite ? "flecheBulleDroite" : (position === euphorik.Util.positionBulleType.bas ? "flecheBulleBas" : "flecheBulleGauche" ))); - + // remplie le paragraphe de la bulle avec le message $("p", m).html(message); - + // réinitialise la position, évite le cas ou la boite est collé à droite et remplie avec un texte la faisant dépassé // dans ce cas la hauteur n'est pas calculé correctement m.css("top", 0).css("left", 0); - + var positionFleche = { left : position === euphorik.Util.positionBulleType.haut || position === euphorik.Util.positionBulleType.bas ? element.offset().left + element.outerWidth() / 2 - f.width() / 2 : @@ -184,7 +184,7 @@ euphorik.Util.prototype.infoBulle = function(message, element, position) { } else if (positionMessage.left < 0) { positionMessage.left = 0; } - + m.css("top", positionMessage.top).css("left", positionMessage.left).show(); f.css("top", positionFleche.top).css("left", positionFleche.left).show(); }, @@ -243,7 +243,7 @@ euphorik.Util.prototype.replaceSelection = function(input, replaceString) { var selectionStart = input.selectionStart; var selectionEnd = input.selectionEnd; input.value = input.value.substring(0, selectionStart) + replaceString + input.value.substring(selectionEnd); - + if (selectionStart != selectionEnd) { // has there been a selection this.setSelectionRange(input, selectionStart, selectionStart + replaceString.length); } else { // set caret @@ -277,7 +277,7 @@ euphorik.Util.prototype.rot13 = function(chaine) { if (pos === ch.length) { return ""; } - + var c = ch.charCodeAt(pos); return String.fromCharCode( c + diff --git a/modules/Makefile b/modules/Makefile index 859cc56..14c229c 100755 --- a/modules/Makefile +++ b/modules/Makefile @@ -1,4 +1,4 @@ -# coding: utf-8 +# coding: utf-8 # Répertoire dans lequel se trouve les modules compilés (beam) rep_ebin = ebin @@ -7,6 +7,7 @@ rep_erl = erl # Répertoire dans lequel se trouve les fichier hrl (définition de record) rep_include = include +rep_include_yaws = /usr/lib/yaws/include # Paramètres du compilateur # il est possible de compiler en natif en executant : @@ -14,14 +15,14 @@ rep_include = include # les différents tests on montrés que ca n'augmentait pas les performances # car très lié à la base de données # TODO : simplifier et éviter les répetitions -ifdef NATIVE - erlc_params = +native -I $(rep_include) -o $(rep_ebin) $< +ifdef NATIVE + erlc_params = +native -I $(rep_include) -I $(rep_include_yaws) -o $(rep_ebin) $< else - erlc_params = -I $(rep_include) -o $(rep_ebin) $< + erlc_params = -I $(rep_include) -I $(rep_include_yaws) -o $(rep_ebin) $< endif # Compilation de toute l'application euphorik -all: $(rep_ebin)/smtp.beam \ +all: $(rep_ebin)/smtp.beam \ $(rep_ebin)/euphorik_bd.beam \ $(rep_ebin)/euphorik_minichat_conversation.beam \ $(rep_ebin)/euphorik_requests.beam \ @@ -31,15 +32,15 @@ $(rep_ebin)/euphorik_bd.beam \ $(rep_ebin)/euphorik_bd_admin.beam \ $(rep_ebin)/euphorik_common.beam \ $(rep_ebin)/euphorik_test.beam - -# Module pour l'envoie d'email -$(rep_ebin)/smtp.beam: $(rep_erl)/smtp.erl - erlc $(erlc_params) + +# Module pour l'envoie d'email +$(rep_ebin)/smtp.beam: $(rep_erl)/smtp.erl + erlc $(erlc_params) # Module pour la gestion des données persistante la BD $(rep_ebin)/euphorik_bd.beam: $(rep_erl)/euphorik_bd.erl $(rep_include)/euphorik_bd.hrl $(rep_include)/euphorik_defines.hrl erlc $(erlc_params) - + # Module pour la mise à jour de la BD $(rep_ebin)/euphorik_bd_admin.beam: $(rep_erl)/euphorik_bd_admin.erl $(rep_include)/euphorik_bd.hrl $(rep_include)/euphorik_defines.hrl erlc $(erlc_params) @@ -47,27 +48,27 @@ $(rep_ebin)/euphorik_bd_admin.beam: $(rep_erl)/euphorik_bd_admin.erl $(rep_inclu # Module permettant l'extraction des conversations du minichat $(rep_ebin)/euphorik_minichat_conversation.beam: $(rep_erl)/euphorik_minichat_conversation.erl $(rep_include)/euphorik_bd.hrl erlc $(erlc_params) - + # Module traitant les requêtes AJAX du client javascript d'euphorik $(rep_ebin)/euphorik_requests.beam: $(rep_erl)/euphorik_requests.erl $(rep_include)/euphorik_defines.hrl erlc $(erlc_params) - + # Module interpretant les messages XML du client $(rep_ebin)/euphorik_protocole.beam: $(rep_erl)/euphorik_protocole.erl $(rep_include)/euphorik_defines.hrl erlc $(erlc_params) - + # Module pour la génération du captcha #$(rep_ebin)/captcha.beam: $(rep_erl)/captcha.erl # erlc $(erlc_params) - + # Module effectuant periodiquement certaines tâches $(rep_ebin)/euphorik_daemon.beam: $(rep_erl)/euphorik_daemon.erl $(rep_include)/euphorik_defines.hrl erlc $(erlc_params) - + # Module avec plein de bordel dedant $(rep_ebin)/euphorik_common.beam: $(rep_erl)/euphorik_common.erl erlc $(erlc_params) - + # Module dédié au tests $(rep_ebin)/euphorik_test.beam: $(rep_erl)/euphorik_test.erl $(rep_include)/euphorik_bd.hrl erlc $(erlc_params) diff --git a/modules/erl/euphorik_bd.erl b/modules/erl/euphorik_bd.erl index f1d5a60..aa51f84 100755 --- a/modules/erl/euphorik_bd.erl +++ b/modules/erl/euphorik_bd.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 permet de gérer les données persistantes lié au site d'euphorik.ch. % Il permet d'ajouter des message, de demande les messages sur une page donnée, etc.. % Ce module utilise une base mnesia. @@ -23,11 +23,11 @@ -module(euphorik_bd). --export([ +-export([ % texte : get_texte/1, get_texte/2, - + % users : nouveau_user/2, nouveau_user/4, @@ -35,14 +35,14 @@ update_date_derniere_connexion/1, update_ip/2, update_pseudo_user/2, - user_by_cookie/1, - user_by_id/1, + user_by_cookie/1, + user_by_id/1, user_by_login/1, user_by_login_password/2, user_by_mess/1, css_from_user_cookie/1, is_ek_master_from_cookie/1, - + % messages : nouveau_message/3, nouveau_message_sys/1, @@ -60,14 +60,14 @@ est_une_reponse_a_user/2, a_repondu_a_message/2, possede_message/2, - + % ip : list_ban/0, ban/2, deban/1, est_banni/1, can_register/1, - + % trolls : trolls/0, trolls/1, @@ -77,9 +77,9 @@ troll_by_id/1, current_troll/0, elire_troll/0, - + % utiles : - resultat_transaction/1, + resultat_transaction/1, get_tuples/3 % must be in a transaction ]). -import(qlc, [e/2, q/1, cursor/2]). @@ -106,23 +106,23 @@ get_texte(Id, _Lang = fr) -> nouveau_user(Cookie, Profile) -> F = fun() -> Id = nouvel_id(user), - User = #user{id = Id, cookie = Cookie, date_creation = now(), date_derniere_connexion = now(), profile = Profile}, + User = #user{id = Id, cookie = Cookie, date_creation = erlang:timestamp(), date_derniere_connexion = erlang:timestamp(), profile = Profile}, mnesia:write(User), User end, resultat_transaction(mnesia:transaction(F)). - - + + % Ajoute un nouveau user et le renvoie nouveau_user(Login, Password, Cookie, Profile) -> F = fun() -> Id = nouvel_id(user), - User = #user{id = Id, cookie = Cookie, login = Login, password = Password, date_creation = now(), date_derniere_connexion = now(), profile = Profile#profile{pseudo = Login}}, + User = #user{id = Id, cookie = Cookie, login = Login, password = Password, date_creation = erlang:timestamp(), date_derniere_connexion = erlang:timestamp(), profile = Profile#profile{pseudo = Login}}, mnesia:write(User), User end, resultat_transaction(mnesia:transaction(F)). - + % Définit les données du profile d'une utilisateur. set_profile(Cookie, Login, Password, Profile) -> @@ -155,7 +155,7 @@ update_date_derniere_connexion(User_id) -> fun() -> case mnesia:wread({user, User_id}) of [User] -> - mnesia:write(User#user{date_derniere_connexion = now()}); + mnesia:write(User#user{date_derniere_connexion = erlang:timestamp()}); _ -> mnesia:abort("update_date_derniere_connexion: User inconnu") end @@ -174,13 +174,13 @@ update_ip(User_id, IP) -> mnesia:abort("update_ip: User inconnu") end end - ). - - + ). + + % Met à jour le pseudo du user update_pseudo_user(UserId, Pseudo) -> mnesia:transaction( - fun() -> + fun() -> case mnesia:wread({user, UserId}) of [#user{profile = Profile} = User] when Profile#profile.pseudo =/= Pseudo -> mnesia:write(User#user{profile = Profile#profile { pseudo = Pseudo } }); @@ -189,7 +189,7 @@ update_pseudo_user(UserId, Pseudo) -> end end ). - + % Est-ce qu'un utilisateur existe en fonction de son cookie ? % Renvoie {ok, User} ou erreur @@ -202,8 +202,8 @@ user_by_cookie(Cookie) -> end end )). - - + + user_by_id(ID) -> resultat_transaction(mnesia:transaction( fun() -> @@ -217,8 +217,8 @@ user_by_id(ID) -> end end )). - - + + user_by_login(Login) -> resultat_transaction(mnesia:transaction( fun() -> @@ -229,24 +229,24 @@ user_by_login(Login) -> 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 + case user_by_cookie(Cookie) of {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( @@ -257,8 +257,8 @@ user_by_login_password(Login, Password) -> end end )). - - + + % Renvoie {ok, User} où User est un #user possédant le message donné. user_by_mess(Id) -> resultat_transaction(mnesia:transaction( @@ -269,26 +269,26 @@ user_by_mess(Id) -> end end )). - - + + % Ajoute un message. Repond_A est une liste d'id auquel le message répond % retourne soit l'id du message soit {erreur, }. nouveau_message(Mess, Auteur_id, Repond_A_ids) -> % regarde si les id 'Repond_A' existent - F = fun() -> + F = fun() -> Repond_a = lists:foldr( fun(Repond_a_id, Acc) -> - case mnesia:read({minichat, Repond_a_id}) of + case mnesia:read({minichat, Repond_a_id}) of [M] -> [M | Acc]; - _ -> Acc % le message n'est pas trouvé + _ -> Acc % le message n'est pas trouvé end - end, + end, [], Repond_A_ids ), Racine_id = case Repond_a of [] -> undefined; - [M | _] -> + [M | _] -> Une_racine = M#minichat.racine_id, % vérification que tout les messages de Repond_a possède la même racine (même conversation) case lists:all(fun(R) -> R#minichat.racine_id =:= Une_racine end, Repond_a) of @@ -297,9 +297,9 @@ nouveau_message(Mess, Auteur_id, Repond_A_ids) -> _ -> {erreur, "Les messages ne font pas partie de la même conversation"} end - end, - if length(Repond_a) =/= length(Repond_A_ids) -> - {erreur, "Un ou plusieurs messages introuvable"}; + end, + if length(Repond_a) =/= length(Repond_A_ids) -> + {erreur, "Un ou plusieurs messages introuvable"}; true -> case Racine_id of {erreur, E} -> {erreur, E}; @@ -308,7 +308,7 @@ nouveau_message(Mess, Auteur_id, Repond_A_ids) -> case mnesia:wread({user, Auteur_id}) of [#user{profile = Profile} = Auteur] -> % comparaison entre la date du dernier poste et maintenant (gestion du flood) - Now = now(), + Now = erlang:timestamp(), Delta = euphorik_common:delta_date_ms(Auteur#user.date_derniere_connexion, Now), Nouvel_indice_flood = Auteur#user.indice_flood + if Delta =< ?DUREE_SPAM -> 2; true -> -1 end, Auteur_maj = Auteur#user{ @@ -321,7 +321,7 @@ nouveau_message(Mess, Auteur_id, Repond_A_ids) -> 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 -> + true -> mnesia:write(Auteur_maj), Id = nouvel_id(minichat), inserer_reponses(Id, Repond_A_ids), @@ -338,19 +338,19 @@ nouveau_message(Mess, Auteur_id, Repond_A_ids) -> _ -> {erreur, "L'auteur du message est introuvable"} end - end + end end end, resultat_transaction(mnesia:transaction(F)). - + % Définit Id_repondant comme étant la réponse à Ids. Ids est une liste d'id. inserer_reponses(Id_repondant, [Id_mess | Reste]) -> mnesia:write(#reponse_minichat{repondant = Id_repondant, cible = Id_mess}), inserer_reponses(Id_repondant, Reste); inserer_reponses(_, []) -> ok. - - + + % Permet de créer un message système. % Renvoie l'id du message système nouveau_message_sys(Mess) -> @@ -358,46 +358,46 @@ nouveau_message_sys(Mess) -> resultat_transaction(mnesia:transaction( fun() -> Id = nouvel_id(minichat), - mnesia:write(#minichat{id = Id, auteur_id = 0, date = now(), pseudo = Profile#profile.pseudo, contenu = Mess, racine_id = Id}), + mnesia:write(#minichat{id = Id, auteur_id = 0, date = erlang:timestamp(), pseudo = Profile#profile.pseudo, contenu = Mess, racine_id = Id}), Id end )). - - + + % Renvoie N messages se trouvant sur la première page -messages(N) -> +messages(N) -> messages(N, 1). -% Renvoie N messages se trouvant sur la page P +% Renvoie N messages se trouvant sur la page P % TODO FIXME : fonction en O(N * P) ! messages(N, P) -> - F = fun() -> - % % #minichat{contenu = contenu_message(E)} + F = fun() -> + % % #minichat{contenu = contenu_message(E)} get_tuples(minichat, mnesia:table_info(minichat, size) - N * P + 1, N) end, - resultat_transaction(mnesia:transaction(F)). - - -get_tuples(Table, First_id, N) -> - lists:foldr( - fun(Id, Acc) -> - case mnesia:read({Table, Id}) of - [T] -> [T | Acc]; - _ -> Acc - end - end, - [], - lists:seq(First_id, First_id + N - 1) - ). - + resultat_transaction(mnesia:transaction(F)). + + +get_tuples(Table, First_id, N) -> + lists:foldr( + fun(Id, Acc) -> + case mnesia:read({Table, Id}) of + [T] -> [T | Acc]; + _ -> Acc + end + end, + [], + lists:seq(First_id, First_id + N - 1) + ). + % Renvoie les messages manquants pour la page P en sachant qu'il y a N message % par page et que le dernier message que l'on possède est Id messages(Id, N, P) -> lists:filter(fun (M) -> M#minichat.id > Id end, messages(N, P)). - - + + % Renvoie {ok, #minichat} (voir #minichat de euphorik_bd.hrl) à partir de son id. message_by_id(Id) -> resultat_transaction(mnesia:transaction( @@ -408,8 +408,8 @@ message_by_id(Id) -> end end )). - - + + % Renvoie le contenu d'un message donnée en fonction du troll associé, à utiliser à l'intérieur d'une transaction. % TODO : Cette fonction pourrait être remplacée par un "outer-join", est-ce possible avec qlc ? contenu_message(E) -> @@ -417,7 +417,7 @@ contenu_message(E) -> [] -> E#minichat.contenu; [T] -> E#minichat.contenu ++ T#troll.content end. - + % Renvoie une liste de message (voir #minichat de euphorik_bd.hrl) à partir d'une liste d'id (Ids). % TODO : optimisations ? serait-ce du O(n) ? @@ -432,7 +432,7 @@ messages_by_ids(Ids) -> ),[{tmpdir, ?KEY_SORT_TEMP_DIR}]) end )). - + % Est-ce qu'un message existe ? Renvoie un boolean. % TODO : ya pas plus simple ? @@ -440,16 +440,16 @@ message_existe(Id) -> resultat_transaction(mnesia:transaction(fun() -> length(e(q([E#minichat.id || E <- mnesia:table(minichat), E#minichat.id =:= Id]), [{tmpdir, ?KEY_SORT_TEMP_DIR}])) =:= 1 end)). - - + + % Renvoie les reponses (utilisé normalement uniquement pendant le debug). reponses() -> F = fun() -> e(q([E || E <- mnesia:table(reponse_minichat)]), [{tmpdir, ?KEY_SORT_TEMP_DIR}]) end, resultat_transaction(mnesia:transaction(F)). - - + + % Renvoie les messages auquel M_id répond. parents(M_id) -> resultat_transaction(mnesia:transaction( @@ -461,8 +461,8 @@ parents(M_id) -> M#minichat.id =:= R#reponse_minichat.cible]), [{tmpdir, ?KEY_SORT_TEMP_DIR}]) end )). - - + + % Renvoie les message qui repondent à M_id enfants(M_id) -> resultat_transaction(mnesia:transaction( @@ -474,8 +474,8 @@ enfants(M_id) -> M#minichat.id =:= R#reponse_minichat.repondant]), [{tmpdir, ?KEY_SORT_TEMP_DIR}]) end )). - - + + % Renvoie les id des parents d'un message M (les messages auquels répond M) % ordrés du plus petit au plus grand.. % On évite d'utiliser qlc pour des raisons de performance @@ -488,11 +488,11 @@ parents_id(M_id) -> fun(#reponse_minichat{cible = Cible}) -> Cible end, Parents )); - _ -> [] + _ -> [] end end)). - - + + % Renvoie les id des enfants d'un message M (les messages qui répondent à M) % ordrés du plus petit au plus grand. % @spec enfants_id(integer()) -> [integer()] @@ -504,10 +504,10 @@ enfants_id(M_id) -> fun(#reponse_minichat{repondant = Repondant}) -> Repondant end, Enfants )); - _ -> [] + _ -> [] end end)). - + % Est-ce que le message Id_mess est une réponse d'une message de Id_user ? % On evite d'utiliser qlc (ce qui était fait avant) pour des raisons de performance. @@ -530,7 +530,7 @@ est_une_reponse_a_user(Id_user, Id_mess) -> end )). - + % Est-ce que Id_user à répondu au message Id_mess % On evite d'utiliser qlc (ce qui était fait avant) pour des raisons de performance. a_repondu_a_message(Id_user, Id_mess) -> @@ -551,8 +551,8 @@ a_repondu_a_message(Id_user, Id_mess) -> end end )). - - + + % Est-ce que Id_user possède Id_mess ? possede_message(Id_user, Id_mess) -> case mnesia:transaction( @@ -563,15 +563,15 @@ possede_message(Id_user, Id_mess) -> {atomic, [Id_user | []]} -> true; _ -> false end. - - + + % renvoie la liste des ip bannies % liste de {ip, temps_restant(en minutes), Users} ou Users est une liste de {pseudo, login} % TODO : déterminer la complexité de cette fonction. (Il n'y a pas d'index sur #user.last_ip) list_ban() -> resultat_transaction(mnesia:transaction( fun() -> - Now = now(), + Now = erlang:timestamp(), e(qlc:keysort(1, q([ { IP#ip_table.ip, @@ -591,19 +591,19 @@ ban(IP, Duration) -> fun() -> case mnesia:wread({ip_table, IP}) of [IP_tuple] -> - mnesia:write(IP_tuple#ip_table{ban = now(), ban_duration = Duration}); + mnesia:write(IP_tuple#ip_table{ban = erlang:timestamp(), ban_duration = Duration}); _ -> - mnesia:write(#ip_table{ip = IP, ban = now(), ban_duration = Duration}) + mnesia:write(#ip_table{ip = IP, ban = erlang:timestamp(), ban_duration = Duration}) end end ). - + % Débanni une ip deban(IP) -> ban(IP, 0). - + % Renvoie soit {true, Temps} où Temps est le temps en minutes pendant lequel le user est encore banni % ou false. est_banni(User_id) -> @@ -618,7 +618,7 @@ est_banni(User_id) -> ]), [{tmpdir, ?KEY_SORT_TEMP_DIR}]) of [{Ban, Ban_duration}] -> Echeance = date_plus_minutes(Ban, Ban_duration), - Now = now(), + Now = erlang:timestamp(), if Echeance < Now -> % l'échéance est passée false; true -> @@ -629,35 +629,35 @@ est_banni(User_id) -> end end )). - - -% Ban est une date tel que retourner par now(). + + +% Ban est une date tel que retourner par erlang:timestamp(). % Ban_duration est un temps en minutes. % retourne une date. date_plus_minutes(Ban, Ban_duration) -> Duration_sec = Ban_duration * 60, {MegaSec, Sec, MicroSec} = Ban, {MegaSec + if Sec + Duration_sec >= 1000000 -> 1; true -> 0 end,(Sec + Duration_sec) rem 1000000, MicroSec}. - -% Si deux enregistrements consequtifs de la même IP sont fait en moins d'une seconde alors + +% Si deux enregistrements consequtifs de la même IP sont fait en moins d'une seconde alors % ip_table.nb_try_register est incrémenté de 1 sinon il est décrémenté de 1 (jusqu'a 0). % Si ip_table.nb_try_register vaut 5 alors l'ip ne peux plus s'enregistrer pour une heure. can_register(IP) -> resultat_transaction(mnesia:transaction( fun() -> case e(q([I || I <- mnesia:table(ip_table), I#ip_table.ip =:= IP]), [{tmpdir, ?KEY_SORT_TEMP_DIR}]) of - [] -> - mnesia:write(#ip_table{ip = IP, date_last_try_register = now()}), + [] -> + mnesia:write(#ip_table{ip = IP, date_last_try_register = erlang:timestamp()}), true; [T] -> - Delta = euphorik_common:delta_date_ms(T#ip_table.date_last_try_register, now()), + Delta = euphorik_common:delta_date_ms(T#ip_table.date_last_try_register, erlang:timestamp()), if T#ip_table.nb_try_register =:= ?NB_MAX_FLOOD_REGISTER, Delta < ?TEMPS_BAN_FLOOD_REGISTER -> false; true -> mnesia:write(T#ip_table{ ip = IP, - date_last_try_register = now(), + date_last_try_register = erlang:timestamp(), nb_try_register = T#ip_table.nb_try_register + if Delta < ?TEMPS_FLOOD_REGISTER -> 1; T#ip_table.nb_try_register > 0 -> -1; true -> 0 end }), true @@ -665,7 +665,7 @@ can_register(IP) -> end end )). - + % Renvoie tous les trolls trolls() -> @@ -674,8 +674,8 @@ trolls() -> e(qlc:keysort(#troll.id, q([T || T <- mnesia:table(troll)])), [{tmpdir, ?KEY_SORT_TEMP_DIR}]) end )). - - + + % Renvoie les trolls manquants posté après Last_id. trolls(Last_id) -> resultat_transaction(mnesia:transaction( @@ -683,8 +683,8 @@ trolls(Last_id) -> e(qlc:keysort(#troll.id, q([T || T <- mnesia:table(troll), T#troll.id > Last_id, T#troll.date_post =:= undefined])), [{tmpdir, ?KEY_SORT_TEMP_DIR}]) end )). - - + + % Crée un nouveau troll. % Renvoie l'id du nouveau troll % ou max_troll_reached_per_user si le nombre de troll posté par l'utilisateur max a été atteind @@ -716,7 +716,7 @@ put_troll(User_id, Content) -> max_troll_reached; true -> Id = nouvel_id(troll), - mnesia:write(#troll{id = Id, id_user = User_id, date_create = now(), content = Content}), + mnesia:write(#troll{id = Id, id_user = User_id, date_create = erlang:timestamp(), content = Content}), Id end; _ -> @@ -738,8 +738,8 @@ mod_troll(Troll_id, Content) -> end end ). - - + + del_troll(Troll_id) -> mnesia:transaction( fun() -> @@ -751,8 +751,8 @@ del_troll(Troll_id) -> end end ). - - + + troll_by_id(Troll_id) -> resultat_transaction(mnesia:transaction( fun() -> @@ -763,7 +763,7 @@ troll_by_id(Troll_id) -> end end )). - + % Renvoie le troll actuel qui se trouve sur la page principale. % Renvois aucun si pas de troll courant. @@ -785,8 +785,8 @@ current_troll() -> % Un message est posté par 'Sys' et le troll elu est lié à ce message % 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(), +elire_troll() -> + {A1,A2,A3} = erlang:timestamp(), random:seed(A1, A2, A3), mnesia:transaction( fun() -> @@ -796,13 +796,13 @@ elire_troll() -> Trolls -> Troll = lists:nth(random:uniform(length(Trolls)), Trolls), Id_message = nouveau_message_sys("Troll de la semaine : "), - Troll2 = Troll#troll{date_post = now(), id_minichat = Id_message}, + Troll2 = Troll#troll{date_post = erlang:timestamp(), id_minichat = Id_message}, mnesia:write(Troll2) end end ). - - + + % Renvoie le résultat d'une transaction (en décomposant le tuple fournit) resultat_transaction({_, T}) -> T. @@ -811,4 +811,3 @@ resultat_transaction({_, T}) -> % Renvoie un nouvel id pour une table donnée nouvel_id(Table) -> mnesia:dirty_update_counter(counter, Table, 1). - \ No newline at end of file diff --git a/modules/erl/euphorik_bd_admin.erl b/modules/erl/euphorik_bd_admin.erl index dca6c2d..0abd2bd 100644 --- a/modules/erl/euphorik_bd_admin.erl +++ b/modules/erl/euphorik_bd_admin.erl @@ -15,7 +15,7 @@ % % You should have received a copy of the GNU General Public License % along with Euphorik. If not, see . -% +% % Module mettant à disposition tout un tas de fonction pour l'administration de la base de données euphorik comme : % - Création de la BD % - Mise à jour de la BD @@ -33,11 +33,11 @@ connect/1, reset/0, update/0, - + backup/1, restore/1, change_node_name/4, - + toggle_ek_master/1, print_users/0, print_users/1, @@ -56,9 +56,9 @@ version_bd() -> mnesia:read({proprietes, version}) end )). - -% Instructions pour créer une nouvelle base : + +% Instructions pour créer une nouvelle base : % $erl -sname yaws -mnesia dir '"/projets/euphorik/BD"' % voir doc/installation.txt % >l(euphorik_bd). @@ -70,7 +70,7 @@ create() -> mnesia:start(), create_tables(), reset(). - + create_tables() -> mnesia:create_table(counter, [ {attributes, record_info(fields, counter)}, @@ -106,8 +106,8 @@ create_tables() -> {disc_copies, [node()]} ]), creer_indexes(). - - + + % mis à part car lors de la reprise de données avec load_textfile les indexes ne sont pas recréés creer_indexes() -> % commence par supprimer les anciens indexes @@ -117,17 +117,17 @@ creer_indexes() -> end, mnesia:table_info(T, index) ) - end, + end, ?TABLES ), mnesia:add_table_index(minichat, auteur_id), mnesia:add_table_index(reponse_minichat, cible), mnesia:add_table_index(user, cookie), mnesia:add_table_index(user, login), - mnesia:add_table_index(troll, date_post), + mnesia:add_table_index(troll, date_post), mnesia:add_table_index(troll, id_minichat). - - + + % Connexion à la base de données de yaws sur overnux connect() -> connect(yaws@flynux). @@ -149,13 +149,13 @@ reset() -> % crée l'utilisateur root mnesia:transaction(fun() -> mnesia:write(#proprietes{nom = version, valeur = ?VERSION_BD}), - User = #user{id = 0, profile = #profile{pseudo = "Sys"}, login = "Sys", date_creation = now(), date_derniere_connexion = now(), ek_master = true}, + User = #user{id = 0, profile = #profile{pseudo = "Sys"}, login = "Sys", date_creation = erlang:timestamp(), date_derniere_connexion = erlang:timestamp(), ek_master = true}, mnesia:write(User), User end), peupler_texte(). - - + + peupler_texte() -> mnesia:transaction(fun() -> mnesia:write(#texte{ id = 10, fr = "Login déjà existant"}), @@ -193,7 +193,7 @@ update() -> _ -> erreur end. - + % Mise à jour de la BD. % attention : il est nécessaire de se trouver dans une transaction. @@ -210,38 +210,38 @@ update(Version) -> end; {error, Raison} -> {error, lists:flatten(io_lib:format("Erreur de création du backup de la version ~w : ~w", [Version, Raison]))} end. - - + + % Applique une modification de la BD pour passer d'une version à la suivante. % crée un backup avant l'application du patch % dans BD/backups nommé "backup" où et le numéro de la version. % 1 -> 2 -patch(1) -> - % Prend un chemin vers la feuille de style de type "css/1/euphorik.css" - % et renvoie "styles/1/euphorik.css" +patch(1) -> + % Prend un chemin vers la feuille de style de type "css/1/euphorik.css" + % et renvoie "styles/1/euphorik.css" Transforme_css = fun("css" ++ Reste) -> - "styles" ++ Reste; - (F) -> F - end, - Traiter_message = fun(M, Racine) -> - F = fun(F, M2) -> % seul moyen à ma connaissance pour faire de la récursion dans une lambda fonction, voir : http://www.nabble.com/Auto-generated-functions-td15279499.html - % met à jour la racine de chaque message qui répond à M - lists:foreach( - fun(M3) -> - mnesia:write(M2#minichat{racine_id = Racine}), - F(F, M3) - end, - euphorik_bd:enfants(M#minichat.id) - ) - end, - F(F, M, Racine) + "styles" ++ Reste; + (F) -> F + end, + Traiter_message = fun(M, Racine) -> + F = fun(F, M2) -> % seul moyen à ma connaissance pour faire de la récursion dans une lambda fonction, voir : http://www.nabble.com/Auto-generated-functions-td15279499.html + % met à jour la racine de chaque message qui répond à M + lists:foreach( + fun(M3) -> + mnesia:write(M2#minichat{racine_id = Racine}), + F(F, M3) + end, + euphorik_bd:enfants(M#minichat.id) + ) + end, + F(F, M, Racine) end, mnesia:create_table(texte, [ {attributes, record_info(fields, texte)}, {disc_copies, [node()]} ]), peupler_texte(), - % traitement des users + % traitement des users mnesia:transform_table( user, fun({user, Id, Cookie, Pseudo, Login, Password, Email, Date_creation, Date_derniere_connexion, Css, Nick_format, View_times, View_tooltips, Indice_flood, _Page_principale, Conversations, Ek_master, Last_ip}) -> @@ -266,34 +266,34 @@ patch(1) -> ) of {aborted, Raison} -> {erreur, Raison}; {atomic, _} -> ok - end; -% 2 -> 3 -patch(2) -> - mnesia:transform_table( - troll, - fun({troll, Id_troll, Id_user, Date_create, Date_post, Content}) -> - % recherche le message associé s'il existe - Id_minichat = case e(q([M || M <- mnesia:table(minichat), element(7, M) =:= Id_troll]), [{tmpdir, ?KEY_SORT_TEMP_DIR}]) of - [M] -> element(2, M); - _ -> undefined - end, - {troll, Id_troll, Id_user, Id_minichat, Date_create, Date_post, Content} - end, - record_info(fields, troll) - ), - %mnesia:del_table_index(minichat, troll_id), - mnesia:transform_table( - minichat, - fun({minichat, Id, Auteur_id, Date, Pseudo, Contenu, _Troll_id, Racine_id}) -> - {minichat, Id, Auteur_id, Date, Pseudo, Contenu, Racine_id, normal} - end, - record_info(fields, minichat) + end; +% 2 -> 3 +patch(2) -> + mnesia:transform_table( + troll, + fun({troll, Id_troll, Id_user, Date_create, Date_post, Content}) -> + % recherche le message associé s'il existe + Id_minichat = case e(q([M || M <- mnesia:table(minichat), element(7, M) =:= Id_troll]), [{tmpdir, ?KEY_SORT_TEMP_DIR}]) of + [M] -> element(2, M); + _ -> undefined + end, + {troll, Id_troll, Id_user, Id_minichat, Date_create, Date_post, Content} + end, + record_info(fields, troll) + ), + %mnesia:del_table_index(minichat, troll_id), + mnesia:transform_table( + minichat, + fun({minichat, Id, Auteur_id, Date, Pseudo, Contenu, _Troll_id, Racine_id}) -> + {minichat, Id, Auteur_id, Date, Pseudo, Contenu, Racine_id, normal} + end, + record_info(fields, minichat) ), mnesia:transaction(fun() -> % comble les trous entre les id non-contigues lists:foreach(fun(Id) -> case mnesia:read({minichat, Id}) of - [] -> + [] -> {ok, #user{profile = Profile}} = euphorik_bd:user_by_id(0), mnesia:write(#minichat{id = Id, auteur_id = 0, date = undefined, pseudo = Profile#profile.pseudo, contenu = "Comblement...", racine_id = Id, status = deleted}); _ -> rien @@ -303,8 +303,8 @@ patch(2) -> ), % la table troll utilise maintenant son index et pas celui de la table minichat (correction d'un vieux bug) mnesia:write(#counter{key = troll, value = mnesia:table_info(minichat, size)}) - end), - creer_indexes(). % uniquement pour l'indice sur id_minichat de la table troll + end), + creer_indexes(). % uniquement pour l'indice sur id_minichat de la table troll % Renvoie le dossier dans lequel les backups sont effectué, ce dossier doit être en écriture. @@ -313,15 +313,15 @@ dossier_backups() -> % Renvoie le fichier (avec le chemin) correspondant à la version Version, par exemple : "/var/euphorik/BD/backups/backup1" -fichier_backup(Version) when is_integer(Version) -> +fichier_backup(Version) when is_integer(Version) -> dossier_backups() ++ "backup" ++ integer_to_list(Version). - + % crée un backup dont le nom est fournit dans le repertoire backups qui se trouve dans le repertoire de la BD. backup(Fichier) -> mnesia:backup(dossier_backups() ++ Fichier). - - + + % Restaure un backup de la BD. restore(Fichier) when is_list(Fichier) -> mnesia:restore(dossier_backups() ++ Fichier, []); @@ -329,7 +329,7 @@ restore(Fichier) when is_list(Fichier) -> % (les données insérées durant les versions plus récentes sont perdues). restore(Version) when is_integer(Version) -> mnesia:restore(fichier_backup(Version), []). % [{default_op, recreate_tables}]). - + % Change le nom du noeud d'un backup. % provient d'ici : http://www.erlang.org/doc/apps/mnesia/Mnesia_chap7.html#6.9 @@ -369,7 +369,7 @@ change_node_name(From, To, Source, Target) -> % Obsolète %~ backup_text(File) -> %~ mnesia:dump_to_textfile(File). -%~ restore_text(File) -> +%~ restore_text(File) -> %~ mnesia:stop(), %~ mnesia:delete_schema([node()]), %~ mnesia:start(), @@ -394,7 +394,7 @@ toggle_ek_master(User_id) -> end end )). - + % Affiche N user trié par leur date de dernière connexion. % Opt est une liste d'option d'affichage : @@ -404,7 +404,7 @@ print_users(N, Opt) -> euphorik_bd:resultat_transaction(mnesia:transaction(fun() -> C = cursor( qlc:keysort( - #user.date_derniere_connexion, + #user.date_derniere_connexion, if AfficheQueLesEkMaster -> q([E || E <- mnesia:table(user), E#user.ek_master =:= true]); true -> @@ -423,8 +423,8 @@ print_users(N, Opt) -> ), qlc:delete_cursor(C) end)). - - + + % Affiche tous les users. print_users(Opt) -> print_users(all_remaining, Opt). @@ -432,14 +432,14 @@ print_users(Opt) -> % Affiche tous les users. print_users() -> print_users(all_remaining, []). - + print_user(User) when is_record(User, user) -> #user{id = Id, profile = #profile{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, @@ -456,11 +456,10 @@ print_user(Login) when is_list(Login) -> {erreur, "Login pas trouvé : " ++ Login} end; % Affichage d'un user en fonction de son id -print_user(Id) when is_integer(Id) -> - case euphorik_bd:user_by_id(Id) of +print_user(Id) when is_integer(Id) -> + case euphorik_bd:user_by_id(Id) of {ok, User} -> print_user(User); _ -> {erreur, "Id pas trouvé : " ++ integer_to_list(Id)} end. - \ No newline at end of file diff --git a/modules/erl/euphorik_common.erl b/modules/erl/euphorik_common.erl index 3806df3..e9e14b7 100644 --- a/modules/erl/euphorik_common.erl +++ b/modules/erl/euphorik_common.erl @@ -15,7 +15,7 @@ % % You should have received a copy of the GNU General Public License % along with Euphorik. If not, see . -% +% % Module avec plein de bordel utile à l'intérieur. % @author G.Burri @@ -40,9 +40,9 @@ ceiling(X) -> Pos when Pos > 0 -> T + 1; _ -> T 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). @@ -50,14 +50,14 @@ delta_date_ms(D1, D2) -> % Retourne la différence entre deux timestamp (erlang:now) en minutes delta_date_minute(D1, D2) -> trunc(delta_date_ms(D1, D2) / 1000 / 60). - + serialize_ip(undefined) -> ""; serialize_ip(IP) -> lists:flatten(io_lib:format("~w.~w.~w.~w", tuple_to_list(IP))). - - + + unserialize_ip(IP) -> case io_lib:fread("~d.~d.~d.~d", IP) of {ok, [A, B, C, D], []} -> {A, B, C, D}; 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)} ]}. diff --git a/modules/erl/euphorik_requests.erl b/modules/erl/euphorik_requests.erl index 3ec70f3..d01c908 100755 --- a/modules/erl/euphorik_requests.erl +++ b/modules/erl/euphorik_requests.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 est fait pour répondre à des requêtes JSON via 'AJAX'. % Il est définit comme 'appmods' pour l'url "request" dans Yaws. % Par exemple http://www.euphorik.ch/request abouti sur la fonction out/1 de ce module. @@ -24,12 +24,12 @@ -module(euphorik_requests). -export([out/1]). --include_lib("yaws/include/yaws_api.hrl"). +-include_lib("yaws_api.hrl"). -include("../include/euphorik_defines.hrl"). % Point d'entrée pour les requêtes AJAX sur http://www.euphorik.ch/request. -out(A) -> +out(A) -> IP = case inet:peername(A#arg.clisock) of {ok, {Adresse, _Port}} -> Adresse; _ -> inconnue @@ -45,8 +45,9 @@ out(A) -> % Décode le message JSON. traiter_message(Contenu, IP) -> % extrait l'entête obligatoire des messages JSON - {ok, {struct, [{header, {struct, [{action, Action}, {version, Version_client}]}} | Reste]}} = json:decode_string(Contenu), - json:encode( + {ok, {struct, [{"header", {struct, [{"action", Action}, {"version", Version_client}]}} | Reste]}} = json2:decode_string(Contenu), + + json2:encode( if Version_client =:= ?VERSION_PROTOCOLE -> traiter_action(Action, Reste, IP); true -> @@ -55,7 +56,7 @@ traiter_message(Contenu, IP) -> ))) end ). - + % Authentification d'un client. traiter_action("authentification", JSON, IP) -> @@ -93,4 +94,3 @@ traiter_action("list_banned_ips", JSON, _) -> % Un ekMaster débannie une ip. traiter_action("unban", JSON, _) -> euphorik_protocole:unban_ip(JSON). - \ No newline at end of file diff --git a/modules/erl/euphorik_test.erl b/modules/erl/euphorik_test.erl index 2cbc1ec..a6fc6a8 100644 --- a/modules/erl/euphorik_test.erl +++ b/modules/erl/euphorik_test.erl @@ -29,10 +29,10 @@ bench_get_messages_avec_2_conversations/0 ]). -include("../include/euphorik_bd.hrl"). - -% les intervalles en seconde min en max entre deux postes de message d'un utilisateur -% le temps d'attente est choisi au hasard entre ces deux valeurs --define(INTERVALLE_MIN, 2). + +% les intervalles en seconde min en max entre deux postes de message d'un utilisateur +% le temps d'attente est choisi au hasard entre ces deux valeurs +-define(INTERVALLE_MIN, 2). -define(INTERVALLE_MAX, 5). @@ -44,8 +44,8 @@ start(N, M) -> fun(Id) -> timer:sleep(100), spawn( - fun() -> - {A1, A2, A3} = now(), + fun() -> + {A1, A2, A3} = erlang:timestamp(), random:seed(A1, A2, A3), loop(Id, M) end @@ -53,10 +53,10 @@ start(N, M) -> end, Ids ). - + stop(Pids) -> lists:foreach(fun(Pid) -> exit(Pid, kill) end, Pids). - + % des trucs qui trainent bench_get_messages() -> T = [ @@ -98,8 +98,8 @@ moyenne_temps(_, _, _, 0, Total, Temps_acc) -> moyenne_temps(Module, Fun, Args, N, Total, Temps_acc) -> {Temps, _} = timer:tc(Module, Fun, Args), moyenne_temps(Module, Fun, Args, N - 1, Total, Temps_acc + Temps). - - + + % Crée N user avec des noms aléatoires et renvoie la liste des id. creer_users(N) -> creer_users(N, []). @@ -112,7 +112,7 @@ creer_users(N, Ids) -> message_rand() -> lists:flatten(message_rand(random:uniform(10), [])). message_rand(0, Mots) -> Mots; -message_rand(N, Mots) -> +message_rand(N, Mots) -> message_rand(N - 1, [mot_rand(random:uniform(2) + 5), $ | Mots]). @@ -122,10 +122,10 @@ mot_rand(L) -> mot_rand(0, Mot) -> Mot; mot_rand(L, Mot) -> mot_rand(L - 1, [random:uniform($z - $a + 1) + $a - 1 | Mot]). - + % Tire au hasard de 0 à 3 messages sur les 10 derniers postés, renvoie une liste de int() -% répartition : +% répartition : % 0 : 0.1 % 1 : 0.95 % 2 : 0.04 @@ -164,22 +164,22 @@ tire_element_rand(N, L, Elements) -> loop(User_id, 0) -> io:format("~p a fini~n", [User_id]); -loop(User_id, M) -> +loop(User_id, M) -> % attend un temp aléatoire compris entre INTERVALLE_MIN sec et INTERVALLE_MAX sec timer:sleep(1000 * (random:uniform(?INTERVALLE_MAX - ?INTERVALLE_MIN + 1) + ?INTERVALLE_MIN - 1)), % poste un message aléatoire par une personne aléatoire répondant à des messages aléatoires {Message, Repond_a} = {message_rand(), messages_id_rand()}, - % io:format("~p poste ~p et repond a ~w~n", [User_id, Message, Repond_a]), + % io:format("~p poste ~p et repond a ~w~n", [User_id, Message, Repond_a]), case euphorik_bd:nouveau_message(Message, User_id, Repond_a) of - {erreur, E} -> + {erreur, E} -> io:format("~p : erreur : ~p~n", [User_id, E]), loop(User_id, M); _ -> loop(User_id, M - 1) end. - - -% Permet de tester la vitesse d'écriture en fonction de la + + +% Permet de tester la vitesse d'écriture en fonction de la % taille de la BD % voir : http://erlang.org/pipermail/erlang-questions/2008-October/038697.html bench_write_minichat(Filename) -> @@ -191,7 +191,7 @@ bench_write_minichat(Filename) -> end, Times ), - file:close(File). + file:close(File). bench_write_minichat(100000, Temps) -> Temps; bench_write_minichat(N, Temps) -> {T, _} = timer:tc(mnesia, transaction, [fun() -> @@ -199,14 +199,13 @@ bench_write_minichat(N, Temps) -> mnesia:write(#minichat{ id = Id, auteur_id = random:uniform(10000), - date = now(), + date = erlang:timestamp(), pseudo = "Test", contenu = "Blabla blabla bla.", racine_id = random:uniform(10000) }) end]), bench_write_minichat(N + 1, if N rem 500 =:= 0 -> [{N, T} | Temps]; true -> Temps end). - - - \ No newline at end of file + + diff --git a/modules/include/euphorik_bd.hrl b/modules/include/euphorik_bd.hrl index 4838b30..2cf466c 100755 --- a/modules/include/euphorik_bd.hrl +++ b/modules/include/euphorik_bd.hrl @@ -30,8 +30,8 @@ key, value }). - - + + % Mémorse toutes les propriétés, entre autre la version des données -record(proprietes, { @@ -53,21 +53,21 @@ { id, % integer auteur_id, % -> #user.id - date, % erlang:now() + date, % erlang:timestamp() pseudo, % chaine de caractère contenu, % chaine de caractère racine_id = undefined, % la racine, par défaut correspond à l'id du message status = normal % can be equal to normal, censored or deleted }). - - + + % type bag % 'repondant' repond à 'cible' -record(reponse_minichat, { repondant, % -> #minichat.id cible % -> #minichat.id - }). + }). -record(profile, % attention : pas une table ! @@ -81,9 +81,9 @@ ostentatious_master = light, % peut valoir invisible, light ou heavy. seulement pour ek_master chat_order = reverse, % peut valoir chrono ou reverse conversations = [] % [{integer(), bool}], la liste des messages correspondant au conversation {racine, reduite?} - }). - - + }). + + -record(user, { id, @@ -91,8 +91,8 @@ login = [], % string() password = [], % string() (md5) profile = #profile{}, - date_creation, % erlang:now() - date_derniere_connexion, % erlang:now(), est mis à jour lors de n'importe quelle activitée (envoie de message par exemple) + date_creation, % erlang:timestamp() + date_derniere_connexion, % erlang:timestamp(), est mis à jour lors de n'importe quelle activitée (envoie de message par exemple) indice_flood = 0, % integer() est incrémenté lorsque l'utilisateur envoie trop rapidement des messages. ek_master = false, last_ip = undefined % integer(), undefined si inconnu @@ -110,15 +110,14 @@ date_last_try_register, date_last_try_login % pour l'instant pas utilisé }). - - + + -record(troll, { id, - id_user, + id_user, id_minichat = undefined, % l'id du message associé - date_create, % erlang:now() - date_post = undefined, % date à laquelle le troll est affiché sur la page principale. undefined initialement puis erlang:now() quand affiché + date_create, % erlang:timestamp() + date_post = undefined, % date à laquelle le troll est affiché sur la page principale. undefined initialement puis erlang:timestamp() quand affiché content % chaine de caractère }). - \ No newline at end of file diff --git a/pages/about.html b/pages/about.html index 74728d2..0a2c501 100644 --- a/pages/about.html +++ b/pages/about.html @@ -1,7 +1,7 @@

euphorik.ch

-

Version : 1.1.5

+

Version : 1.1.6

Auteur : GBurri

FAQ

diff --git a/tools/jsmin.rb b/tools/jsmin.rb old mode 100644 new mode 100755 diff --git a/tools/tools.rb b/tools/tools.rb old mode 100644 new mode 100755 index 8b14954..323926f --- a/tools/tools.rb +++ b/tools/tools.rb @@ -37,16 +37,16 @@ along with Euphorik. If not, see . # Classe permettant la vérification du code JS pas jslint. # Passe en revu chaque fichier js de manière récursive à partir d'un dossier de départ.s -class VerifJS - +class VerifJS + def initialize(dossier) @dossier = dossier end - + def verifier verifierRecur(@dossier) end - + def verifierRecur(dossier) Dir.foreach(dossier){|fichier| cheminComplet = "#{dossier}/#{fichier}" @@ -56,7 +56,7 @@ class VerifJS end elsif fichier[-3, 3] == '.js' puts "== Vérification de #{cheminComplet} ==" - # TODO : mettre un if pour la version windows si dessous + # TODO : mettre un if pour la version windows si dessous #system("java org.mozilla.javascript.tools.shell.Main jslint.js #{cheminComplet}") system("rhino ./tools/jslint.js #{cheminComplet}") # puts $?.exitstatus @@ -70,7 +70,7 @@ class VerifJS end # Classe de gestion de la version -class Version +class Version # @param dossier la racine du site (par exemple "/var/www/euphorik") def initialize(dossier) @dossier = dossier @@ -81,9 +81,9 @@ class Version @fichiers = ['/pages/about.html'] @balise = /().*?(<\/a>)/ end - + # met à jour la version dans les fichiers @fichiers - def maj + def maj @fichiers.each{|fichier| fichier = @dossier + fichier lines = IO.readlines(fichier) @@ -91,7 +91,7 @@ class Version lines.each{|l| io.write(l.sub(@balise){|m| $1 + @version + $2 + @version + $3}) } - } + } } end end @@ -101,11 +101,11 @@ class MiseEnProd # obsolète ! @@rep_remote = '/var/www/euphorik' @@host = 'euphorik.ch' - + def initialize(racine) Dir.chdir(racine) - end - + end + # L'emplacement ou sont copié les fichiers # A définir avant la mise en prod def uri=(uri) @@ -113,20 +113,20 @@ class MiseEnProd @uri = plop[0] @rep = plop[1] end - + # Effectue la mise en production. def miseEnProd copierFichiers() maj('yaws') end - + # Effectue la mise en préproduction. def miseEnPreProd copierFichiers() lancerYaws() maj('yaws_dev') end - + def copierFichiers compiler_partie_serveuse() creer_repertoire_bd() @@ -135,14 +135,14 @@ class MiseEnProd copie_modules_serveurs() set_droits_fichiers() end - + def lancerYaws creer_rep("tools") system("rsync tools/yaws.conf #{@uri}:#{@rep}/tools") system("rsync tools/start_yaws.sh #{@uri}:#{@rep}/tools") system("ssh #{@uri} \"cd #{@rep}/tools; screen -d -m -S yaws_dev ./start_yaws.sh\"") end - + def exec(commande) system("ssh #{@uri} \"cd #{@rep} && #{commande}\"") end @@ -153,7 +153,7 @@ class MiseEnProd rescue end end - + def compiler_partie_serveuse log "compilation des modules serveur" Dir.chdir('modules') @@ -164,18 +164,18 @@ class MiseEnProd end Dir.chdir('..') end - - def creer_repertoire_bd - log "création du répertoire de la base de données" + + def creer_repertoire_bd + log "création du répertoire de la base de données" # création du repertoire BD creer_rep('BD') creer_rep('BD/backups') exec("chmod -R g+w BD") end - + # css, images, html, etc.. def copier_partie_statique - log "copie de la partie statique" + log "copie de la partie statique" uri = "#{@uri}:#{@rep}" system("awk '$0 !~ /prod=\"delete\"/' index.yaws | ssh #{@uri} \" cat > #{@rep}/index.yaws\"") system("rsync favicon.ico #{uri}") @@ -183,22 +183,23 @@ class MiseEnProd system("rsync --delete -r pages #{uri}") system("rsync --delete -r --exclude 'autres' img #{uri}") end - + # minification et package des fichiers js dans euphorik.js def pack_js - log "minification, assemblage et copie du javascript" + log "minification, assemblage et copie du javascript" rep_js = 'js' creer_rep(rep_js) # jquery.js et euphorik.js doivent se trouve en premier fichiers = ['js/libs/jquery.js', 'js/euphorik.js'].concat(get_fichiers_js(rep_js)) - commande_cat = "cat " + commande_cat = "cat " fichiers.each{|f| commande_cat += f + " " } #copie des js concaténés avec minification - system("#{commande_cat} | tools/jsmin.rb | ssh #{@uri} \"cd #{@rep} && cat > #{rep_js}/euphorik.js\"") + # tools/jsmin.rb | + system("#{commande_cat} | ssh #{@uri} \"cd #{@rep} && cat > #{rep_js}/euphorik.js\"") end - + #renvoie une liste des fichiers js def get_fichiers_js(rep) fichiers = [] @@ -211,35 +212,35 @@ class MiseEnProd fichiers << fichier end end - } + } return fichiers end - - def copie_modules_serveurs - log "copie des modules du serveur" + + def copie_modules_serveurs + log "copie des modules du serveur" # copie des modules erlang creer_rep('modules') system("rsync -r --exclude 'euphorik_test.beam' modules/ebin #{@uri}:#{@rep}/modules") system("rsync -r modules/include #{@uri}:#{@rep}/modules") end - + def set_droits_fichiers - log "attribution des droits sur les fichiers" + log "attribution des droits sur les fichiers" # attribution des droits exec("chmod -R g+rx .") end - + # noeud : le nom du noeud sur lequel le script de mise en prod est exécuté # Execute le script 'mise_en_prod.erl' sur le serveur afin de : # - Recharger les modules # - Mettre à jour la base de données def maj(noeud) - log "rechargement des modules serveur et mise à jour de la base de données" + log "rechargement des modules serveur et mise à jour de la base de données" # execution du script de mise à jour system("cat tools/mise_en_prod.erl | ssh #{@uri} \"cat > /tmp/mise_en_prod.erl\"") system("ssh #{@uri} \"chmod u+x /tmp/mise_en_prod.erl; /tmp/mise_en_prod.erl #{noeud}; rm /tmp/mise_en_prod.erl\"") end - + def log(message) puts "----- #{message} -----" end @@ -248,19 +249,19 @@ end # Traite la ligne de commande lorsque tools.rb est utilisé comme tel class Commande - def initialize + def initialize Dir.chdir("..") @miseEnProd = MiseEnProd.new(".") @verifJS = VerifJS.new("js") @version = Version.new(".") end - + def traiter if ARGV.size == 0 afficherUsage return end - + case ARGV[0] when 'prod' @version.maj() @@ -276,7 +277,7 @@ class Commande @version.maj() end end - + def afficherUsage puts "Usage : tools.rb (prod | pre | js | version)\n" + " prod : Mise en production\n" +