SpaceFox a écrit 1787 commentaires

  • [^] # Re: Lapin compris

    Posté par  (site web personnel, Mastodon) . En réponse au journal Du développement full-stack en Java. Évalué à 7.

    En fait ça fonctionne parce que ton code est contraire aux bonnes pratiques de Java.

    Un constructeur ça sert à construire un objet, pas à lancer un traitement bloquant. Je me demande d'ailleurs si ça ne peut pas casser certains mécanismes de la JVM d’avoir ce genre de comportement.

    L'une des conséquences, c'est que l'utilisation d'un tel comportement est purement incompréhensible pour le lecteur du code.

    La connaissance libre : https://zestedesavoir.com

  • [^] # Re: ... et pas qu'un ...

    Posté par  (site web personnel, Mastodon) . En réponse au journal Du développement full-stack en Java. Évalué à 10. Dernière modification le 03 août 2018 à 16:18.

    Être obligé de jongler avec plusieurs langages en fonction du type d'application à développer ? Non merci, je préfère pouvoir développer tout type d'application en utilisant un seul langage ; c'est beaucoup plus efficace.

    Ou pas.

    Mon stage de fin d'études c'était justement la migration d'une application mono-langage (Progress 4GL) à une pile de langages plus spécialisés (Java, HTML, JS, SQL). Eh bien la pile de langages était infiniment plus facile à comprendre et utiliser que l'espèce de soupe qui prétendait tout faire, des requêtes à la BDD aux effets présentés à l'utilisateur.


    Ça fait la troisième fois (en comptant la version Node.js) qu'ont dit que mon code est nettement perfectible (ce dont j'ai parfaitement conscience, comme je l'ai à maintes fois indiqué). Je veux bien, mais est-ce que quelqu'un aurait la bonté de me montrer ne fût-ce qu'un exemple de ce qui ne va pas, et comment le corriger, histoire que j'ai l'occasion d'améliorer mon code ? Ou alors je vais finir pas penser que mon code n'est peut-être pas aussi mauvais que certains le prétendent !

    Je vais être sec aussi, mais en ce qui concerne ton code Java, il n'y a tellement rien qui va que te l'expliquer en détail est un travail si énorme que c'est décourageant.

    Si je prends juste en exemple le TODO MVC :

    • Le fichier s'appelle main.java mais ne contient pas de classe publique qui s'appelle main.
    • Le fichier n'est pas dans un package.
    • Deux classes (package-protected) dans le même fichier.
    • Tu utilises des new String("…").
    • int index = this.index; ?!
    • D'ailleurs tu passes ton temps à masquer la variable de classe index avec des variables locales index.
    • Tu n'utilises pas les possibilités de l'API standard (l'itérateur ligne 43, le while ligne 197 par exemple, ou tout le bloc de if / else if à partir de la ligne 230).
    • if ( false ) { !?
    • La ligne 273 ressemble beaucoup à une boucle infinie.
    • Ton main lance Exception, ce qu'il ne devrait pas faire, et en plus rien dans ton code ne déclare que cette Exception devrait être lancée.
    • Tu appelles des méthodes avec leur package complet au lieu de les importer (info.q37.xdhq.XDH.readAsset).
    • Tout est ultra-manuel : génération de XML à la main en dur dans le code, méthode escape que tu as réinventé, etc.
    • Tout est en vrac dans un seul fichier : personnellement je ne comprends pas ce que fait ce code à sa simple lecture.
    • J'imagine que le index de la classe TodoMVC pourrait être nullable pour gérer le cas particulier au lieu d'utiliser la valeur spécifique -1.
    • Dans la méthode push tu modifies ton paramètre xml.
    • La logique contient des triples négations : dans handleCount tu as un else sur une condition négative qui active un truc qui s'appelle HideBidule. Au final ça fait quoi ?
    • D'ailleurs le projet s'appelle TODO MVC mais n'est pas du tout du MVC ?!
    • Je passe sur les détails comme le formatage, la présence d'un System.out, l'import de packages complets ou le manque d'accolades.
    • Je passe aussi sur ton API qui me semble très étrange, comme ces méthodes qui attendent un tableau de tableau de String.

    Rien qu'en re-présentant le code correctement, ça donnerait quelque chose comme :

    package todomvc;
    /*
        Copyright (C) 2018 Claude SIMON (http://q37.info/contact/).
    
        This file is part of XDHq.
    
        XDHq is free software: you can redistribute it and/or
        modify it under the terms of the GNU Affero General Public License as
        published by the Free Software Foundation, either version 3 of the
        License, or (at your option) any later version.
    
        XDHq is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
        Affero General Public License for more details.
    
        You should have received a copy of the GNU Affero General Public License
        along with XDHq If not, see <http://www.gnu.org/licenses/>.
    */
    
    import info.q37.atlas.Atlas;
    import info.q37.atlas.DOM;
    import info.q37.atlas.GUI;
    import info.q37.xdhq.XDH;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.ListIterator;
    
    class Todo {
        public boolean completed;
        public String label;
    
        Todo(String label, boolean completed) {
            this.completed = completed;
            this.label = label;
        }
    
        Todo(String label) {
            this(label, false);
        }
    }
    
    class TodoMVC extends Atlas {
        private Boolean exclude;
        private int index = -1;
        private List<Todo> todos;
    
        private int itemsLeft() {
            return (int) todos.stream()
                    .filter(todo -> !todo.completed)
                    .count();
        }
    
        private String escape( String text ) {
            return text
                    .replace( "&", "&amp;")
                    .replace( "\"", "&quot;")
                    .replace( "<", "&lt;")
                    .replace( ">", "&gt;");
        }
    
        private String push(Todo todo, int id, String xml) {
            return xml
                    + "<Todo"
                    + " id=\"" + id + "\""
                    + " completed=\"" + todo.completed + "\">"
                    + escape(todo.label)
                    + "</Todo>\n";
        }
    
        private void displayCount(DOM dom, int count) {
            String text = "";
    
            switch (count) {
            case 0:
                break;
            case 1:
                text = "1 item left";
                break;
            default:
                text = count + " items left";
                break;
            }
    
            dom.setContent("Count", text);
        }
    
        private void handleCount( DOM dom ) {
            int count = itemsLeft();
    
            if (count != todos.size())
                dom.disableElement("HideClearCompleted");
            else
                dom.enableElement("HideClearCompleted");
    
            displayCount(dom, count);
        }
    
        private void displayTodos( DOM dom ) {
    
            String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<XDHTML>\n<Todos>\n";
    
            ListIterator<Todo> li = todos.listIterator();
            while (li.hasNext()) {
                int index = li.nextIndex();
    
                Todo todo = li.next();
    
                if ((exclude == null) || (todo.completed != exclude))
                    xml = push(todo, index, xml);
            }
    
            xml = xml + "</Todos>\n</XDHTML>";
    
            dom.setLayoutXSL("Todos", xml, "Todos.xsl");
            handleCount( dom );
        }
    
        private void submitNew( DOM dom ) {
            String content = dom.getContent("Input");
            dom.setContent("Input", "");
    
            if (!"".equals(content.trim())) {
                todos.add(0, new Todo(content));
                displayTodos( dom );
            }
        }
    
        private void submitModification( DOM dom ) {
            int index = this.index;
            this.index = -1;
    
            String content = dom.getContent("Input." + index);
            dom.setContent("Input." + index, "");
    
            if (!"".equals(content.trim())) {
                todos.set(index, new Todo(content, todos.get(index).completed));
    
                dom.setContent("Label." + index, escape(content));
    
                dom.removeClasses( new String[][] { { "View." + index, "hide" }, { "Todo." + index, "editing" } } );
            } else {
                todos.remove(index);
                displayTodos( dom );
            }
        }
    
        private void toggle( DOM dom, String id) {
            int index = Integer.parseInt(id);
            Todo todo = todos.get(index);
    
            todo.completed = !todo.completed;
    
            todos.set(index, todo);
    
            dom.toggleClass( "Todo." + id, "completed");
            dom.toggleClass( "Todo." + id, "active");
    
            if (exclude != null)
                displayTodos( dom );
            else
                handleCount( dom  );
        }
    
        private void all( DOM dom ) {
            exclude = null;
    
            dom.addClass("All", "selected");
            dom.removeClasses(new String[][] { { "Active", "selected" }, { "Completed", "selected" } } );
            dom.disableElements(new String[]{"HideActive","HideCompleted"});
        }
    
        private void active( DOM dom ) {
            exclude = true;
    
            dom.addClass("Active", "selected");
            dom.removeClasses(new String[][] { { "All", "selected" }, { "Completed", "selected" } } );
            dom.disableElement("HideActive");
            dom.enableElement("HideCompleted");
    }
    
        private void completed( DOM dom ) {
            exclude = false;
    
            dom.addClass("Completed", "selected");
            dom.removeClasses( new String[][] { { "All", "selected" }, { "Active", "selected" } } );
            dom.disableElement("HideCompleted");
            dom.enableElement("HideActive");
        }
    
        private void clear( DOM dom ) {
    
            todos.removeIf(todo -> todo.completed);
    
            displayTodos( dom );
        }
    
        private void edit(DOM dom, String id) {
            String content = dom.getContent(id);
    
            index = Integer.parseInt(content);
    
            dom.addClasses( new String[][] { { "View." + content, "hide" }, { id, "editing" } } );
            dom.setContent("Input." + content, todos.get(index).label);
            dom.focus("Input." + content);
        }
    
        private void cancel( DOM dom ) {
            int index = this.index;
            this.index = -1;
    
            dom.setContent("Input." + index, "");
            dom.removeClasses( new String[][] { { "View." + index, "hide" }, { "Todo." + index, "editing" } } );
        }
    
        public TodoMVC() {
            System.out.println("Connection detected...");
    
            todos = new ArrayList<>();
    
        }
    
        public void handle( DOM dom, String action, String id ) {
            switch (action) {
                case "Connect":
                    dom.headUp(XDH.readAsset("HeadDEMO.html"));
                    dom.setLayout("", XDH.readAsset("Main.html"));
                    dom.focus("Input");
                    dom.disableElements(new String[]{"HideActive", "HideCompleted"});
                    displayTodos(dom);
                    break;
                case "Submit":
                    if (index == -1)
                        submitNew(dom);
                    else
                        submitModification(dom);
                    break;
                case "Destroy":
                    todos.remove(Integer.parseInt(dom.getContent(id)));
                    displayTodos(dom);
                    break;
                case "Toggle":
                    toggle(dom, id);
                    break;
                case "All":
                    all(dom);
                    break;
                case "Active":
                    active(dom);
                    break;
                case "Completed":
                    completed(dom);
                    break;
                case "Clear":
                    clear(dom);
                    break;
                case "Edit":
                    edit(dom, id);
                    break;
                case "Cancel":
                    cancel(dom);
                    break;
                default:
                    throw new RuntimeException("No or unknown action !!!");
            }
        }
    
        public static void main(String[] args) {
            String dir;
    
            if ( System.getenv("EPEIOS_SRC") == null )
                dir = ".";
            else
                dir = "TodoMVC";
    
            launch("Connect", dir, GUI.DEFAULT, args);
    
            while (true)
                new TodoMVC();
        }
    }

    (non testé).

    La connaissance libre : https://zestedesavoir.com

  • # Il vaudrait mieux te mettre en contact avec quelqu'un qui connait Java

    Posté par  (site web personnel, Mastodon) . En réponse au journal Du développement full-stack en Java. Évalué à 10.

    Je te conseille de te rapprocher d'un développeur Java, au moins pour tes exemples de présentations, pour deux raisons :

    1. Parce qu'il existe déjà un outil qui fait ça, c'est GWT – et que donc tu y seras obligatoirement comparé.
    2. Parce que ton code ressemble tellement peu à du Java que tes exemples te desservent au lieu de te vendre.

    La connaissance libre : https://zestedesavoir.com

  • [^] # Re: Le scroll est devenu plus lent ? (Chrome-like)

    Posté par  (site web personnel, Mastodon) . En réponse au journal LinuxFr.org : seconde quinzaine de juillet 2018. Évalué à 2. Dernière modification le 01 août 2018 à 15:30.

    J'ignorais l'existence de cette propriété. Après avoir joué avec la démo de Mozilla, je te confirme que mon ressenti vient complètement de l'implémentation de scroll-behavior: smooth; sous Chrome-like quand il y a beaucoup à scroller (et donc c'est pas un problème de perfs, ce qui est le principal).

    C'est peut-être une habitude à prendre : LinuxFr est à ma connaissance le seul site que j'utilise à avoir des pages dans lesquels je fais des sauts aussi longs. Les autres ont soit de la pagination, soit du chargement au scroll, et dans les deux cas ça ne s'utilise pas pareil.

    La connaissance libre : https://zestedesavoir.com

  • # Le scroll est devenu plus lent ? (Chrome-like)

    Posté par  (site web personnel, Mastodon) . En réponse au journal LinuxFr.org : seconde quinzaine de juillet 2018. Évalué à 2.

    pas mal de petites modifications sur le site en ce moment, n'hésitez pas à me dire si vous voyez des choses bizarres, cassées ou qui vous semblent moins bien qu'avant

    J'ai l'impression que le scroll est devenu plus lent qu'avant, au moins sur les moteurs de rendus type Chromium.

    Cas de test :

    1. Trouver une page avec beaucoup de commentaires (comme celle-ci).
    2. Cliquer sur le lien [ qui renvoie au dernier commentaire par ordre chronologique.

    Comportement attendu : ça scrolle rapidement jusqu'au commertaire.

    Comportement obtenu : le scroll est assez lent, me semble-t-il plus lent qu'avant, surtout en début de scroll (c'est lent et ça accélère).

    Comportement observé sous Vivaldi 1.15.1147.55 (Stable channel) (64 bits) (moteur JS : V8 6.5.254.41) et Chromium 68.0.3440.7.

    Firefox 61.0.1 (64 bits) ne semble pas avoir ce souci.

    Ordinateur :

    • Linux Mint 19 Cinnamon à jour,
    • noyau 4.15.0-29-generic, Intel© Core™ i3-7100 CPU @ 3.90GHz × 2,
    • 16 Go de RAM,
    • carte graphique Advanced Micro Devices, Inc. [AMD/ATI] Oland GL FirePro W2100 avec les drivers libres.

    La connaissance libre : https://zestedesavoir.com

  • [^] # Re: digital, vraiment ?

    Posté par  (site web personnel, Mastodon) . En réponse au journal Pollution numérique. Évalué à 5.

    Ça je suis d'accord, ma question portait vraiment sur les impressions de mails.

    La connaissance libre : https://zestedesavoir.com

  • [^] # Re: digital, vraiment ?

    Posté par  (site web personnel, Mastodon) . En réponse au journal Pollution numérique. Évalué à 7.

    C'est encore fréquent les gens comme « Monique » ? Je pensais naïvement qu'avec l'habitude et les écrans plats qui explosent beaucoup moins les yeux que les écrans cathodiques, on en voyait de moins en moins.

    La connaissance libre : https://zestedesavoir.com

  • [^] # Re: Google fait du « beau travail » ?

    Posté par  (site web personnel, Mastodon) . En réponse au journal Google + Commission Européenne = KABOUM. Évalué à 3.

    Google n'utilise plus le « don't be evil ».

    La connaissance libre : https://zestedesavoir.com

  • [^] # Re: Compte créé le 13 juillet...

    Posté par  (site web personnel, Mastodon) . En réponse au journal Tout ce qu’il faut savoir sur le langage PHP. Évalué à 2. Dernière modification le 18 juillet 2018 à 12:10.

    Je confirme, et la page en question liée arrive juste derrière.

    La connaissance libre : https://zestedesavoir.com

  • [^] # Re: Autre lien intéressant

    Posté par  (site web personnel, Mastodon) . En réponse au journal Tout ce qu’il faut savoir sur le langage PHP. Évalué à 8.

    Et surtout très daté en plus de sa mauvaise foi. PHP Sadness est plus intéressant à mon sens, parce que factuel et surtout maintenu à jour.

    La connaissance libre : https://zestedesavoir.com

  • # Pourquoi ce lien et maintenant ?

    Posté par  (site web personnel, Mastodon) . En réponse au journal Tout ce qu’il faut savoir sur le langage PHP. Évalué à 10.

    Pourquoi partager un lien qui a maintenant plus de huit ans et demie – une éternité en terme d'informatique ?

    Pour donner un repère temporel, quand l'article a été écrit, la version courante de PHP était la 5.2, il n'y avait ni trait ni espace de noms ni rien de plus moderne, et PHP 4 était déprécié depuis moins de 6 mois.

    La connaissance libre : https://zestedesavoir.com

  • [^] # Re: Cause psychologique ?

    Posté par  (site web personnel, Mastodon) . En réponse au journal J'ai testé... me faire électriser. Évalué à 5. Dernière modification le 13 juillet 2018 à 09:27.

    Hypnotiques pour suspendre la conscience (et supprimer la mémoire), curares pour relâcher les muscles, opioïdes pour supprimer la douleur. Mais c'est l'association des trois (et pas seulement une partie) qui constitue l'anesthésie.

    Cf la vidéo que j'ai liée plus haut pour les détails.

    La connaissance libre : https://zestedesavoir.com

  • [^] # Re: Cause psychologique ?

    Posté par  (site web personnel, Mastodon) . En réponse au journal J'ai testé... me faire électriser. Évalué à 3. Dernière modification le 12 juillet 2018 à 18:21.

    J'ai plus la réponse en tête mais je suis presque sûr qu'elle est dans la vidéo que j'ai liée plus haut.

    La connaissance libre : https://zestedesavoir.com

  • [^] # Re: Quel est le rapport avec le monde du libre ou de l'informatique?

    Posté par  (site web personnel, Mastodon) . En réponse au journal J'ai testé... me faire électriser. Évalué à 7.

    « Seulement » ceux qui ne sont pas en « rapport avec le monde du libre ou de l'informatique » j'imagine…

    La connaissance libre : https://zestedesavoir.com

  • [^] # Re: Cause psychologique ?

    Posté par  (site web personnel, Mastodon) . En réponse au journal J'ai testé... me faire électriser. Évalué à 5.

    Une ressource intéressante sur le sujet : https://www.youtube.com/watch?v=wYD1qBhGtlk

    La connaissance libre : https://zestedesavoir.com

  • [^] # Re: as tu plus d'info sur Sapiens

    Posté par  (site web personnel, Mastodon) . En réponse au journal Lecture pour cet été. Évalué à 5.

    Ça me fait penser à un bouquin, dont j'ai hélas oublié le titre et l'auteur exacts. C'était un truc du genre « Une chronique du XXIème Siècle », écrit juste avant 1990. C'était censé raconter le futur, du « présent » de l'époque jusqu'à 2100. Et surtout, ça commençait par une longue intro qui expliquait que contrairement à tous les autres ouvrages de ce type, les auteurs avaient utilisé des méthodes scientifiques et sérieuses, donc leurs prévisions devaient être précises et crédibles.

    Aujourd'hui, on constate que c'est un ramassis de conneries qui s'est planté sur toute la ligne (et c'était visiblement un livre français, on y parlait de Minitel 2).

    La connaissance libre : https://zestedesavoir.com

  • # Cartes postales

    Posté par  (site web personnel, Mastodon) . En réponse au journal Gmail at confidentialité : il semblerait que plein de monde puisse lire vos emails. Évalué à 10.

    On appréhende beaucoup mieux la problématique de la confidentialité des mails en se les représentant comme des cartes postales et non comme du courrier dans une enveloppe.

    Une carte postale, tu as beau la remettre toi-même à la poste centrale pour éviter les intermédiaires, n'importe qui dans le processus de distribution (et en particulier le facteur qui va l'amener au destinataire) peut la lire. Ou la laisser lire à quelqu'un d'autre si ça l'amuse.

    La connaissance libre : https://zestedesavoir.com

  • [^] # Re: Licence

    Posté par  (site web personnel, Mastodon) . En réponse au journal Tectonique de la pâte thermique (Linux Pratique). Évalué à 2.

    En effet, ça n'aurait aucun sens…

    La connaissance libre : https://zestedesavoir.com

  • [^] # Re: Licence

    Posté par  (site web personnel, Mastodon) . En réponse au journal Tectonique de la pâte thermique (Linux Pratique). Évalué à 10.

    Sauf que si la licence est une Creative Commons avec une clause « No Derivatives » ou « Non Commercial », ce n'est pas une licence libre et ce quel que soit le nombre de guillemets que tu mets à « libre ». Ce ne sont que des licences de libre diffusion, ce qui est sensiblement différent.

    D'ailleurs, le sélecteur de licence de Creative Commons le précise lui-même dans l'encadré qui te dit si c'est une licence « Free Culture ».

    Pour moi, on est clairement dans un cas d'openwashing avec ce mode de fonctionnement : les Éditions Diamond te font croire que tu peux publier, attendre six mois et avoir une version libre de ton article ; alors que tu ne peux que publier, attendre six mois, et diffuser toi-même ton article. Ce qui en soit est un modèle tout à fait acceptable, tant que tu n'essaie pas de faire croire à quiconque que les articles sont « libérés » (au sens de la culture libre).

    La connaissance libre : https://zestedesavoir.com

  • [^] # Re: Faut juste bien l'appliquer [TM]

    Posté par  (site web personnel, Mastodon) . En réponse au journal Tectonique de la pâte thermique (Linux Pratique). Évalué à 10.

    Je n'arrive pas à savoir si c'est de l'incompétence ou de la malveillance que de balancer une image pareille.

    Plus probablement de l'humour.

    La connaissance libre : https://zestedesavoir.com

  • [^] # Re: Bonne résolution

    Posté par  (site web personnel, Mastodon) . En réponse à la dépêche 20 ans de LinuxFr.org. Évalué à 3. Dernière modification le 29 juin 2018 à 16:54.

    La page sur les nimages m'informe que justement elles étaient une source importante de problèmes de sexisme, et ont provoqué divers débats en particulier à l'été 2012.

    Je ne traine activement ici que depuis plus récemment que ça, et j'ai rarement vu de nimages. J'ai l'impression que cette partie du problème a finalement été résolue, du moins dans les grandes lignes :)

    La connaissance libre : https://zestedesavoir.com

  • [^] # Re: Le libre dans mon travail

    Posté par  (site web personnel, Mastodon) . En réponse au journal France Culture: que reste-t-il du logiciel libre ?. Évalué à 2.

    Ça rejoint la fameuse théorie de « négociation » qui consiste à dire que si on a pas tout ce qui est demandé, alors on ne prends rien : toute solution intermédiaire est rejetée.

    On la retrouve en vrac à la CGT, chez le MEDEF ou à la FSF et dans beaucoup d'autres organisations. C'est globalement utile d'avoir des gens durs sur leur ligne ; mais est-ce vraiment une manière efficace de négocier ? Je ne pense pas (et vus les résultats des dernières élections syndicales, il semblerait que je ne sois pas le seul).

    C'est particulièrement frustrant quand tu te retrouves à conserver un statu quo inintéressant et à abandonner 90 % d'éléments qui t'arrangent parce que 10 % sont considérés comme inacceptables.

    La connaissance libre : https://zestedesavoir.com

  • [^] # Re: TLDR

    Posté par  (site web personnel, Mastodon) . En réponse au journal Migrer Windows 10 d'un disque BIOS/MBR, vers un SSD en mode UEFI/GPT avec des logiciels libres. Évalué à 6.

    Le mot-clé était installe…

    La connaissance libre : https://zestedesavoir.com

  • [^] # Re: TLDR

    Posté par  (site web personnel, Mastodon) . En réponse au journal Migrer Windows 10 d'un disque BIOS/MBR, vers un SSD en mode UEFI/GPT avec des logiciels libres. Évalué à 2.

    Pour avoir installé les deux, je confirme : les ordinateurs pré-installés ont la clé enregistrée directement dans le BIOS. Ça marche tellement bien que si tu réinstalles Windows sur une clé USB sur un ordinateur avec Windows pré-installé, ça détecte directement la licence.

    Mais évidemment sur les PC nus, ça ne fonctionne pas.

    Ce que je ne sais pas, c'est ce qui se passe si tu reinstalles Windows sur un PC assemblé, mais sans formater la partition EFI : est-ce qu'il te redemande ta licence ?

    La connaissance libre : https://zestedesavoir.com

  • [^] # Re: TLDR

    Posté par  (site web personnel, Mastodon) . En réponse au journal Migrer Windows 10 d'un disque BIOS/MBR, vers un SSD en mode UEFI/GPT avec des logiciels libres. Évalué à 4.

    Les SGBD. Même mon dernier essai en date avec la version Docker de Oracle 12cR2 m'a pris près de deux heures (et 15 Go). Si tu as effectivement une technique qui permet d'installer ça « en quelques secondes » et qu'elle n'est pas secrète, je suis preneur.

    La connaissance libre : https://zestedesavoir.com