| ajaxchat/addmessage.py |
| 1 | #!/usr/bin/env python |
| 2 | # -*- coding: utf8 -*- |
| 3 | |
| 4 | print "Content-Type: text/html" |
| 5 | print |
| 6 | |
| 7 | import cgi |
| 8 | import fcntl |
| 9 | from xml.dom import minidom |
| 10 | from md5 import md5 |
| 11 | |
| 12 | # Récupération du message de l'utilisateur : |
| 13 | replace_map_nick = { |
| 14 | '\n':'', |
| 15 | '\r':'', |
| 16 | ' ':'', |
| 17 | ':':'', |
| 18 | } |
| 19 | replace_map_message = { |
| 20 | '\n':'', |
| 21 | '\r':'', |
| 22 | } |
| 23 | contenu_formulaire = cgi.FieldStorage() |
| 24 | message = contenu_formulaire.getvalue('message','') |
| 25 | for to, by in replace_map_message.items(): message = message.replace(to, by) |
| 26 | nick = contenu_formulaire.getvalue('nick','Anonyme') |
| 27 | for to, by in replace_map_nick.items(): nick = nick.replace(to, by) |
| 28 | if not(nick): nick = 'Anonyme' |
| 29 | |
| 30 | # Ouverture de l'ancien fichier dans un arbre dom : |
| 31 | |
| 32 | document = minidom.parse('messages.xml') |
| 33 | root = document.getElementsByTagName('chat')[0] |
| 34 | index = root.getAttributeNode('index').nodeValue |
| 35 | |
| 36 | xml_miaou = document.createElement('miaou') |
| 37 | xml_id = document.createElement('id') |
| 38 | xml_id.appendChild(document.createTextNode(index)) |
| 39 | xml_nick = document.createElement('nick') |
| 40 | xml_nick.setAttribute('color', str(int(md5(nick).hexdigest()[0], 16))) |
| 41 | xml_nick.appendChild(document.createTextNode(nick)) |
| 42 | xml_message = document.createElement('message') |
| 43 | xml_message.appendChild(document.createTextNode(message)) |
| 44 | |
| 45 | xml_miaou.appendChild(xml_id) |
| 46 | xml_miaou.appendChild(xml_nick) |
| 47 | xml_miaou.appendChild(xml_message) |
| 48 | root.appendChild(xml_miaou) |
| 49 | |
| 50 | index = str(int(index) + 1) |
| 51 | root.setAttribute('index', index) |
| 52 | |
| 53 | messages_xml = open('messages.xml', 'w') |
| 54 | fcntl.flock(messages_xml.fileno(), fcntl.LOCK_EX) # Gestion des accès concurrents |
| 55 | |
| 56 | messages_xml.write(document.toprettyxml()) |
| ajaxchat/ajaxchat.js |
| 1 | function ajax_updatechat() { |
| 2 | /* Mettre à jour les messages du chat */ |
| 3 | document.getElementById("updating").style.visibility = 'visible'; |
| 4 | var xhr = null; |
| 5 | if (window.XMLHttpRequest) { |
| 6 | xhr = new XMLHttpRequest(); |
| 7 | } |
| 8 | else if (window.ActiveXObject) { |
| 9 | xhr = new ActiveXObject("Microsoft.XMLHTTP"); |
| 10 | } |
| 11 | else { |
| 12 | alert("Votre navigateur n'est pas supporté par cette application"); |
| 13 | } |
| 14 | |
| 15 | xhr.onreadystatechange = function() { |
| 16 | if (xhr.readyState == 4) { // Quand c'est tout prêt |
| 17 | var chatXML = xhr.responseXML.documentElement; |
| 18 | var miaous = chatXML.getElementsByTagName('miaou'); |
| 19 | for (i = 0; i < miaous.length; i++) { |
| 20 | var id = miaous[i].getElementsByTagName('id')[0].firstChild.data |
| 21 | var nick = miaous[i].getElementsByTagName('nick')[0].firstChild.data; |
| 22 | var nickcolor = miaous[i].getElementsByTagName('nick')[0].attributes.getNamedItem('color').nodeValue; |
| 23 | var msg = miaous[i].getElementsByTagName('message')[0].firstChild.data; |
| 24 | if (parseInt(id) > window.last_id) { |
| 25 | // Création du li |
| 26 | var li = document.createElement('li'); |
| 27 | var nickspan = document.createElement('span'); |
| 28 | var nickspancolor = document.createAttribute('class'); |
| 29 | nickspancolor.value = 'nick'+nickcolor; |
| 30 | nickspan.setAttributeNode(nickspancolor); |
| 31 | nickspan.appendChild(document.createTextNode('<'+nick+'> ')); |
| 32 | li.appendChild(nickspan); |
| 33 | li.appendChild(document.createTextNode(msg)); |
| 34 | // Et ajout dans l'ul |
| 35 | document.getElementById("chat").appendChild(li); |
| 36 | // Autoscroll de la liste : |
| 37 | var scroll = document.getElementById("chat").scrollHeight - document.getElementById("chat").offsetHeight |
| 38 | document.getElementById("chat").scrollTop = scroll+100 // +100 pour éviter les dépassements :) |
| 39 | window.last_id = parseInt(id); |
| 40 | } |
| 41 | |
| 42 | } |
| 43 | document.getElementById("updating").style.visibility = 'hidden'; |
| 44 | } |
| 45 | }; |
| 46 | |
| 47 | xhr.open('GET', 'http://lab.inaps.org/ajax-chat/chat.py?lastid='+encodeURIComponent(window.last_id), true); |
| 48 | xhr.send(null); |
| 49 | |
| 50 | } |
| 51 | |
| 52 | function ajax_sendmessage(event) { |
| 53 | /* Envoyer un message sur le chat */ |
| 54 | document.getElementById("sendmessage").style.display = 'none'; |
| 55 | document.getElementById("sending").style.display = 'inline'; |
| 56 | var xhr = null; |
| 57 | if (window.XMLHttpRequest) { |
| 58 | xhr = new XMLHttpRequest(); |
| 59 | } |
| 60 | else if (window.ActiveXObject) { |
| 61 | xhr = new ActiveXObject("Microsoft.XMLHTTP"); |
| 62 | } |
| 63 | else { |
| 64 | alert("Votre navigateur n'est pas supporté par cette application"); |
| 65 | } |
| 66 | |
| 67 | xhr.onreadystatechange=function() { |
| 68 | if(xhr.readyState == 4) { |
| 69 | document.getElementById("message").value = ''; |
| 70 | document.getElementById("sending").style.display = 'none'; |
| 71 | document.getElementById("sendmessage").style.display = 'inline'; |
| 72 | ajax_updatechat(); |
| 73 | } |
| 74 | }; |
| 75 | xhr.open("POST", "addmessage.py", true); |
| 76 | xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); |
| 77 | xhr.send('message=' + encodeURIComponent(document.getElementById("message").value) + '&nick=' + encodeURIComponent(document.getElementById("nick").value)); |
| 78 | event.preventDefault(); // Annuler l'envois du formulaire |
| 79 | } |
| 80 | |
| 81 | function onUpdateChat(event) { |
| 82 | ajax_updatechat(); |
| 83 | event.preventDefault(); |
| 84 | } |
| 85 | |
| 86 | function addEvent(element, event, func) { |
| 87 | /* Ajouter un évènement sur un élément */ |
| 88 | if (element.addEventListener) |
| 89 | element.addEventListener(event, func, false); |
| 90 | else if (element.attachEvent) |
| 91 | element.attachEvent("on" + event, func); |
| 92 | } |
| 93 | |
| 94 | function onSwitchAutorefresh(event) { |
| 95 | if (window.autoresfresh == 1) { |
| 96 | // autorefresh off !! |
| 97 | document.getElementById("autoupdate").src = 'autoupdate_off.png'; |
| 98 | document.getElementById("manualupdate").src = 'manual_update.png'; |
| 99 | window.clearInterval(window.autorefreshinterval); |
| 100 | window.autoresfresh = 0; |
| 101 | } |
| 102 | else { |
| 103 | // autorefresh on !! |
| 104 | document.getElementById("autoupdate").src = 'autoupdate_on.png'; |
| 105 | document.getElementById("manualupdate").src = 'manual_update_disabled.png'; |
| 106 | window.autorefreshinterval = window.setInterval(ajax_updatechat, 2000); |
| 107 | window.autoresfresh = 1; |
| 108 | } |
| 109 | event.preventDefault(); |
| 110 | } |
| 111 | |
| 112 | function onLoadEvent(event) { |
| 113 | /* Evenement exécuté à la fin du chargement de la page */ |
| 114 | ajax_updatechat(); |
| 115 | document.getElementById("nick").value = 'Chatteur' + Math.floor(Math.random() * 100); |
| 116 | addEvent(document.getElementById("formmsg"), 'submit', ajax_sendmessage); |
| 117 | addEvent(document.getElementById("manualupdateevent"), 'click', onUpdateChat); |
| 118 | // Par défaut : lancer le mode autorefresh |
| 119 | document.getElementById("manualupdate").src = 'manual_update_disabled.png' |
| 120 | window.autorefreshinterval = window.setInterval(ajax_updatechat, 2000); |
| 121 | window.autoresfresh = 1; |
| 122 | addEvent(document.getElementById("autoupdateevent"), 'click', onSwitchAutorefresh); |
| 123 | } |
| 124 | |
| 125 | var last_id = 0; |
| 126 | var autorefresh; |
| 127 | var autorefreshinterval; |
| 128 | addEvent(window, 'load', onLoadEvent); |