IUT : TP jQuery / jQuery Mobile

La note sera décomposée ainsi :

(1) Sur 4 points – Le site HTML (bootstrap / design) et le code source du site HTML (HTML5, indentation + sortie à l’imprimante correcte)
(2) Sur 10 points : Les appels AJAX, ainsi que des effets avec jQuery + de la construction dynamique d’éléments avec jQuery (indentation Php et jQuery / JavaScript + sortie à l’imprimante correcte)
(3) Sur 6 points : le site HTML mobile avec du jQuery Mobile et des appels AJAX (indentation + sortie à l’imprimante correcte, sachant que, encore une fois, j’en attends moins du site mobile que du site principal).

Prenez en compte ces avertissements :
– interdiction d’utiliser une librairie JavaScript qui ne vienne pas des sites officiels jQuery, jQueryUI, jQuery Mobile ou Bootstrap
– dernier délai : fin de semaine de notre dernier cours, soit dimanche à minuit. Passé ce délai ce sera 1 pt par 2 heures de retard (je prendrai en compte la date de réception du mail) ;
– copie sur une autre personne (« je se savais pas comment implémenter telle ou telle fonctionnalité dont j’avais besoin pour aller plus loin, je l’ai copiée sur un autre »), deux cas se distinguent :
– si la personne est clairement nommée, cette fonctionnalité ne sera pas prise en compte dans la notation (= 0 pour cette fonctionnalité) ;
– si la personne est clairement nommée, et qu’il y a une amélioration de la fonctionnalité : note pour la fonctionnalité divisée par 2 (uniquement la moitié du travail a été faite) ;
– 0 aux deux personnes sinon ;
– si je m’aperçois que vous avez bêtement copié collé des sources Internet, je vous convoquerai pour vous demander de m’expliquer la fonctionnalité, et deux cas se distinguent :
– si vous ne savez pas m’expliquer le code alors 0 ;
– si vous savez m’expliquer tout le code alors votre note totale sera divisée par vous + le nombre de contributeurs à ce projet, ce qui se rapprochera certainement de 0 aussi.
– rendu du TP possible : vous ne m’envoyez que le code HTML et JavaScript, et un lien vers un site sur lequel vous avez tout réalisé. Ainsi, je n’aurais pas à installer / regarder ce qui a été fait en Php (ou Python pour ceux qui sont allés plus loin que les cours Php (oui, il y en a !)), et je regarderai ce que j’ai cité plus haut.

ISEN Institut Supérieur de l’Électronique et du Numérique : cours e-Commerce


Cliquez ici pour télécharger le cours.

Rappel pour les vhosts :

  • Rajouter la correspondance dans le fichier Hosts
  • Créer le vhost (exemple dans le PDF ci dessus) dans sites-avalaible puis lien symbolique dans sites-enabled via l’ordre ln -s ../site-avalaible/nomdelaconf nomdelaconf.conf
  • Redémarrer Apache : sudo service apache2 restart

Une vulnérabilité critique affectant Windows Server 2003 ne sera pas corrigée

C’est bien, je vais enfin avoir l’argument massue pour tous ceux qui critiquent Linux : une faille critique sur Windows Server 2003 qui permet de devenir maître du système à distance ne sera jamais corrigée.

Je vous rappelle qu’on paie pour une license, et que la sécurité fait partie des choses pour lesquelles on paie (on paie en partie pour les mises à jour et ces dernières corrigent les bogues et problèmes de sécurité).

Il suffira donc juste d’avoir le programme qui permet d’exploiter cette faille et si on veut être méchant, on le pourra !

Tout est expliqué ici : sur developpez.com

Le tag <blink> : il est né à partir d’une bonne cuite. Histoire vraie.

Vous ne me croiriez pas si j’étais le seul à le dire, mais le tag blink qui fait clignoter le texte de manière affreuse et agressive, est né d’une grosse fête entre ingénieurs, qui, bien échaudés par quelques verres, se sont marrés en pensant à une idée stupide.

L’histoire tout en langue de Shakespeare ici.

NodeJS et MongoDB : requête « JOIN » fonctionnelle

// Exemple copié collé et adapté sur stackoverflow :              
// http://stackoverflow.com/questions/15630770/node-js-check-if-path-is-file-or-directory
// http://stackoverflow.com/questions/7268033/basic-static-file-server-in-nodejs 
//                                                                               
var http = require('http'),                                            
    url = require('url'),                          
    fs = require('fs'),                            
    mongoose = require('mongoose'),                
    fileSystem = require('fs'),                    
    path = require('path');                        
var mimeTypes = {                                                                
    "html": "text/html",                 
    "jpeg": "image/jpeg",                
    "jpg": "image/jpeg",                 
    "png": "image/png",                  
    "js": "text/javascript",             
    "css": "text/css"};                  
                                                                                 
var server;                                                                      
var Schema = mongoose.Schema;                                                    
                                                                                 
mongoose.connect('mongodb://localhost/test');                          
var db = mongoose.connection;                                                    
                                                                                 
var creneauSchema = new Schema({                                                 
    libelle:    String,                                      
    date_debut: { type: Date, default: Date.now },           
    date_fin:   { type: Date, default: Date.now },           
    heure_debut: Number,                                     
    duree: Number,                                           
    creneauxJours_id: { type: Schema.Types.ObjectId, ref: 'CreneauJours' }
});                                                                              
var Creneau = db.model('Creneau', creneauSchema);                      
                                                                                 
var creneauJoursSchema = new Schema({                                            
    jours_semaine: [Number]                                  
});                                                                              
var CreneauJours = db.model('CreneauJours', creneauJoursSchema);       
                                                                                 
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function () {                                          
    console.log('DB connexion reussie');           
    //var cj = new CreneauJours({                            
    //    jours_semaine: [1,2,3,4,5]                         
    //});                                                    
    //cj.save(function (err) {                               
    //    if (err) { return console.log(err); }              
    //    console.log('Écriture réussie');
    //    var c = new Creneau({                              
    //        libelle: "Après midi à 16 heures",
    //        date_debut: new Date(2010, 1, 1),              
    //        date_fin:   new Date(2020, 1, 1),              
    //        heure_debut: 16,                               
    //        duree: 120,                                    
    //        creneauxJours_id: cj._id                       
    //    });                                                
    //    c.save(function (err) {                            
    //        if (err) { return console.log(err); }          
    //        console.log('Écriture 2 réussie');
    //    });                                                
    //});                                                    
    //return;                                                
                                                                                 
    server = http.createServer(function (request, response) {
        if (request.url=='/creneaux') {
            console.log("> JSON");
            Creneau  
            .find({})
            .select('_id libelle date_debut date_fin heure_debut duree creneauxJours_id')
            .populate('creneauxJours_id')
            .exec(function (err, c) {
                if (err) {
                    return console.log(err);
                }
                console.log(c);
                var retour='[';
                for (var i = 0; i < c.length; i++) {
                    retour += '{'
                        + 'id:' + JSON.stringify(c[i]._id)+', '
                        + 'libelle:' + JSON.stringify(c[i].libelle)+', '
                        + 'date_debut:' + c[i].date_debut+', '
                        + 'date_fin:' + c[i].date_fin+', '
                        + 'heure_debut:' + c[i].heure_debut+', '
                        + 'duree:' + c[i].duree+', '
                        + 'jours:[' + c[i].creneauxJours_id.jours_semaine + ']'
                        + '},';
                };
                /* Enlever la dernière virgule : */
                retour=retour.substr(0, retour.length-1)+']';
                response.writeHead(200, {
                    'Cache-Control': 'no-cache, must-revalidate',
                    'Expires': 'Mon, 26 Jul 1997 05:00:00 GMT',
                    'Content-type': 'application/json'
                });
                response.end(retour);
            });      
            // Stopper tout traitement :
            return;  
        }                                
        var uri = url.parse(request.url).pathname;
        var filename = path.join(process.cwd(), uri);
        console.log("> " + filename);
        fs.exists(filename, function(exists) {
            if ((!exists) || (fs.lstatSync(filename).isDirectory())) {
                console.log(">> fichier inexistant : " + filename);
                response.writeHead(200, {'Content-Type': 'text/plain'});
                response.write('404 Not Found\n');
                response.end();
                // Stopper tout traitement :
                return;
            }        
            var mimeType = mimeTypes[path.extname(filename).split(".")[1]];
            response.writeHead(200, {'Content-Type':mimeType});
                                                                                 
            var fileStream = fs.createReadStream(filename);
            fileStream.pipe(response);
        });                              
                                                                                 
    });                                                      
    // Listen on port 8000, IP defaults to 127.0.0.1         
    server.listen(8000);                                     
    // Put a friendly message on the terminal                
    console.log("Server running at http://127.0.0.1:8000/");
});

Exemple de serveur NodeJs et mongoose

Fichier téléchargeable ici.

Code shell pour tester le serveur :

wget --quiet 127.0.0.1:8000/personnes -O - ; echo

Lien vers la dernière version du cours en PDF : ici.

Pour faire des jointures avec mongoose: populate. Lien ici.

Article à lire sur les Promise ici.

Exemple de création sous Visual Studio : ici.

Activemq : principe de messagerie interne producteur / consommateur

J’ai eu un besoin que je pensais assez particulier, mais qui, en fait, dans certains cas, semble tellement récurrent que beaucoup de choses ont déjà été faites dans ce sens.
Mon besoin est simple :

J’ai un site distant qui est d’accord pour qu’on l’interroge en lui demandant des informations sur des Ids, mais pas très souvent : une demande toute les 5 secondes. Par contre, lors de la demande, on peut lui faire passer plein d’Ids (jusqu’à 100 !).

Donc j’ai fait un script Php, lancé à la main, qui tourne en boucle, et qui va interroger ce fameux site, toutes les 5 secondes.
Une fois ce script fait, j’ai besoin que l’on puisse préciser « à la main » les Ids. Je fais donc un site Internet, et je mets à disposition de tout le monde la possibilité d’entrer des Ids « à la main ».

Problème

La demande Internet peut se faire n’importe quand, et il faut que la réponse soit rapide, donc que la demande soit immédiatement inclue dans le « paquet » lors de la prochaine interrogation. De plus, il peut y avoir plein de demandes à la fois. Et elles doivent toutes s’ajouter facilement.

Solutions

Plusieurs solutions sont possibles :

  1. Utiliser une sorte de dossiers « partagés » où d’un côté le Web/Php dépose un fichier avec un Id, et attend dans un autre dossier la réponse comportant le même nom de fichier ; gros problème : ce n’est pas une méthode 100% fiable ;
  2. Faire un serveur interne qui attend des informations, et lorsque son timer tombe, hop, fait la demande. Gros problème : écrire un vrai serveur Web en Php n’est pas une chose facile, et je n’ai pas le temps de faire tout ça ;
  3. Faire une écriture en base de données pour chaque demande Web, et du côté script, faire un simple « SELECT * FROM… WHERE DATE_DEMANDE IS NULL » (ou quelque chose comme ça). Problème bloquant : comment faire pour signaler à chaque demande Web que leur réponse est disponible ?
  4. Dernière solution : utiliser quelque chose qui existe déjà et tourne très bien : un serveur producteur/consommateur (je l’appelle comme ça mais ce n’est pas le vrai nom). Il implémente en gros tout ce que je demande : d’un côté le client qui envoie des messages, et peut – ou pas – attendre un retour de manière bloquante, et de l’autre côté, le serveur qui lit les messages qui arrivent quand il en a envie, et peut leur répondre facilement – quand je dis « facilement », je parle du point de vue du code à faire en Php.

Solution finale

La dernière solution existe, tourne depuis bien longtemps, fait partie de l’association Apache, et a une implémentation en Php, soit tout ce que je veux : cliquez ici pour plus d’informations : http://activemq.apache.org/

Résumé mémo pour mon installation sous Linux (car si je change de serveur j’aurais besoin de me souvenir de ce qui suit !) :

  • apt-get install activemq
  • Ce qui m’a fait perdre beaucoup de temps : la configuration est la même que le principe available/enabled de la configuration du serveur Web Apache, à la différence près qu’une configuration n’est pas un fichier simple, mais un dossier. Il faut donc faire un lien symbolique dans le dossier enabled sur le dossier d’exemple : sudo ln -s ../instances-available/main/
  • Pour le lancer, faire le grand classique et ne pas suivre d’autres suggestions moisies qu’on trouve un peu partout sur le Web. Simplement service activemq start
  • Enfin, installer en Php. Sur Debian, si on enlève le temps de recherche, ça prend deux minutes maximum : pecl install stomp. L’installation de stomp pour activemq va compiler une extension pour Php. Il suffit de l’inclure dans /etc/php.ini (je l’ai ajouté en fin de fichier, ça a parfaitement fonctionné) : extension=stomp.so. Au cas où, n’oubliez pas de redémarrer le serveur Web ! service apache2 restart

Et voilà tout fonctionne ! Le meilleur exemple – et plus parlant – à mon sens se trouve ici. Code très simple et efficace.