jtremesay a écrit 321 commentaires

  • [^] # Re: Clairement, ce type de lien appelle à un journal, avec une opinion.

    Posté par  (site web personnel) . En réponse au lien The Case Against Rocky Linux. Évalué à 4 (+2/-0).

    Y'a un petit bouton pour changer la langue de l'article.

  • # France cul

    Posté par  (site web personnel) . En réponse au journal La publicité sur Radio France - podcasts, direct et appli. Évalué à 10.

  • # jssg

    Posté par  (site web personnel) . En réponse au lien Ivre, il crée un générateur de sites statiques avec 300 lignes de python et django. Évalué à 4.

    Jusque là, jssg était hébergé dans le dépot de mon site.

    Pour simplifier la réutilisation par autrui, je lui ai crée un dépôt dédié.

    J'ai viré l'intégration de vite/typescript pour simplifier le truc.

    Du contenu d'exemple a été fourni sous la très libérale licence CC0.

    Have fun!

  • [^] # Re: Je vais regarder ça, ça m'intéresse bien...

    Posté par  (site web personnel) . En réponse au lien Ivre, il crée un générateur de sites statiques avec 300 lignes de python et django. Évalué à 3.

    J'ai regardé tardivement et le fait que ce soit une techno Django a induit ma réflexion en erreur.

    Tkt, moi aussi ça m'a pas mal perturbé pendant le dev.

    "Alors si je fais comment ça ça m'arrangera beaucoup pour l'écriture du contenu mais ça va me niquer les perfs sur la prod. réalisation wait, y'aura pas de code sur la prod, j'mef des perfs !"

  • [^] # Re: Je vais regarder ça, ça m'intéresse bien...

    Posté par  (site web personnel) . En réponse au lien Ivre, il crée un générateur de sites statiques avec 300 lignes de python et django. Évalué à 3.

    (ce serait probablement différent avec AGPL qui donnerait plus de contrainte : là, il faudrait certainement redistribuer les sources aux gens qui visitent le site et ça serait très contraignant).

    Ben je ne suis pas sûr. La licence AGPL a vraiment été pensé pour les logiciels de type services avec lequel l'utilisateur final interagis, ce qui n'est pas le cas de JSSG dans son usage normal. (tu PEUX l'utiliser en mode serveur pour dev comme une app Django normale, mais ce n'est pas recommandé de l'utiliser en prod pour ça)

    Par contre, en effet, si le générateur de site statique est destiné à être utilisé par d'autres gens, le séparer du contenu d'un site en particulier paraîtrait plus malin.

    Pour l'instant, c'est avant tout pour mon usage perso.

    J'en ai parlé ici pour faire un retour d'expérience de «oui, aussi con que puisse paraître l'idée, il est possible et même facile de faire un générateur static avec Django, et voilà comment j'ai fait» parce que je sais qu'il y a toujours quelqu'un d'intéressé par mes expérimentations idiotes.

    Les templates, si pas spécifique au site de Jonathan, c'est un moins cool en NC en revanche en effet. Pas d'utilisation commerciale, ça veut dire pas d'utilisation sur un site commercial. J'ai énormément de mal avec le NC, au delà du fait que ce n'est pas libre, son champ d'application est potentiellement très large. C'est plus ou moins du code que personne ne peut réutiliser. Aussi bien, "pas d'utilisation sur un site commercial" pourrait vouloir dire "pas d'utilisation sur un site". Potentiellement, il suffit de vendre un t-shirt ou un mug via le site pour que ça ne marche plus.

    Les templates sont spécifique à mon site. Mais il est vrai que je les avais foutu dans la base de code du générateur pour me simplifier la vie, ce qui peut porter à confusion.

    Hier soir, j'ai extrait tout mon contenu perso du générateur; il ne devrait plus y avoir de problème de contamination par la CC-BY-NC-SA.

  • [^] # Re: Je vais regarder ça, ça m'intéresse bien...

    Posté par  (site web personnel) . En réponse au lien Ivre, il crée un générateur de sites statiques avec 300 lignes de python et django. Évalué à 7.

    (dernière version connue qui marche)

    ça nécessite Django 5 (et donc visiblement python 3.10) ; c'est un frein. A priori en mettant comme dépendance Django 4.2.9 ça semble opérationnel.

    C'est une dépendance faible à Django 5. J'ai pinné sur les dernières versions disponibles. Mais vu que je n'utilise rien de spécifique à la 5, ça devrait assez bien tourner avec la 4.

    il y a des migrations et une base SQLite. Je ne m'y attendais pas (c'est pas fondamentalement un problème)

    euh… non ? Enfin, ça fait toujours très plaisir à django que tu fasses ./manage.py migrate avant le ./manage.py runserver. Mais sinon, je n'ai pas de migrations et je n'utilise pas la db.

    je ne connais pas vite, je m'attendais à ne pas avoir besoin de la partie "js" pour une utilisation basique mais ça plante directement avec une erreur 500, ce qui est perturbant.

    pour mon cas d'usage, ça m'arrange d'avoir le front géré par Vite plutôt que par Django. Et ouais, Django grogne quand npm run vite n'est pas lancé.

    Tu peux désactiver ça en ne chargeant pas l'app django_vite_plugin .

    Faudra aussi remplacer dans les templates les {% vite 'bla' %} par des `{% static 'bla' %}

    C'est d'autant plus perturbant que le debug est désactivé par défaut

    C'est géré par la var env DJANGO_DEBUG qui doit être à true pour activer le debug :

    DJANGO_DEBUG=true ./manage.py
    

    Si tu as direnv d'installé, la variable est appliquée automatiquement qrace à ça ce fichier. (et en plus, il crée et charge automatiquement le venv. N'est-ce pas magnifique ?)

    la licence est problématique pour l'usage que j'envisage (sites pro algoo) :

    Comme indiqué par raphj ("Tu vas faire tourner le code GPL chez toi (sur ton ordi de dev, dans la CI ou sur le serveur), et pas chez les gens qui visitent le site. Tu peux tout à fait l'étendre ou l'adapter sans jamais devoir redistribuer les modifications parce que l'outil reste de ce fait interne."), je ne pense pas que la GPL soit bloquante pour que vous pussiez utiliser et modifier le générateur.

    ce qui peut m'intéresser ce sont aussi les templates de base qui sont si j'ai bien compris sous licence CC-BY-NC-SA. Je ne peux donc pas partir de ces templates pour faire un site professionnel : je dois réécrire le code.

    effectivement, les templates font plus partis du contenus que du générateur et seraient donc plutôt sous CC-BY-NC-SA. Mais honnêtement, je ne suis pas sûr qu'il y ai assez de truc dedans pour que ça qualifie pour une véritable protection de ma propriété intellectuelle.

    Au pire, cadeau, 2 templates sous licence Unlicense :

    page.html :

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>{{ object.title }}</title>
    </head>
    <body>
        <h1>{{ object.title }}</h1>
        {{ object.content_md|safe }}
    </body>
    </html>

    post.html :

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>{{ object.title }}</title>
    </head>
    <body>
        Publié le {{ object.timestamp|date:"Y-m-d" }}.
    
        <h1>{{ object.title }}</h1>
        {{ object.content_md|safe }}
    </body>
    </html>

    J'imagine que le sujet de la licence est lié au fait que la techno (le moteur JSSG) et le contenu éditorial sont dans un repo unique.

    ouais. À la base, c'était le dépôt du site lui même. Pis j'ai fini par y ajouter le générateur quand j'ai vu que je ne trouvais pas mon bonheur parmis les outils existant.

    l'intégration des métadonnées dans les contenus directement (j'avais prototypé qqchose de similaire il y a quelques temps mais je n'étais pas allé au bout de la démarche - ce que tu as fait)

    J'ai rien inventé, j'ai volé l'idée chez Hugo

    J'imagine très aisément ce changement de licence en séparant le repo "moteur JSSG" (avec un squelette de site qui serait neutre) et le repo "site" (ton site) ; je ne sais pas si c'est qqchose qui t'intéresse et/ou que tu es prêt à faire

    J'ai réorganisé le dépot pour déplacer tout mon contenu perso en dehors du sous dossier jssg pour faciliter la réutilisation par autrui.

    À terme, le générateur finira probablement dans son propre dépot. Mais pour l'instant, ça m'était plus simple de faire un mono-dépot.

    (et dans tous les cas, les licences que tu as choisies pour le moteur et pour les templates sont peut-être bien réfléchies et que tu ne souhaites pas les modifier).

    Semi-réfléchi. Par défaut, j'ai une politique de «j'ai pas de problème à coder gratuitement pour enrichir les bien communs, mais j'ai pas envie que quelqu'un puisse se faire des montagnes de fric en privatisant mes conneries».

    Ou comme le dit raphj, «Tout le monde ne veut pas faciliter la tâche des éditeurs de logiciels propriétaires gratuitement / dans leur temps libre».

  • [^] # Re: Je vais regarder ça, ça m'intéresse bien...

    Posté par  (site web personnel) . En réponse au lien Ivre, il crée un générateur de sites statiques avec 300 lignes de python et django. Évalué à 5.

    C'est plus vaste que ça … Je vais jeter un coup d'œil et je te redis.

    j'accepte les abonnements galae start en pourboire ;)

    Tu gères les meta,opengraph etc comme méta données ?

    "oui et non". Non parce que je n'utilise pas ce genre de chose.

    Mais oui vu que chaque document peut contenir des meta-data et être accesible dans les templates

    Genre là je défini le title de la page en utilisant le document courant.

    Du coup, dans ton ma_page.md :

    ---
    title: ma page
    bidule: machin
    ---
    
    hello moto

    et dans ton base.html :

    <meta property="og:title" content="{{ object.title }} " />
    <meta property="og:url" content="{% url 'page' object.slug %}" />
    <meta property="og:bidule" content="{{ object.meta.bidule }}" />
  • [^] # Re: Je me demande si...

    Posté par  (site web personnel) . En réponse au lien Ivre, il crée un générateur de sites statiques avec 300 lignes de python et django. Évalué à 4.

    Il faut le bon dosage. Ça demande des années de pratique pour le trouver !

  • [^] # Re: Je vais regarder ça, ça m'intéresse bien...

    Posté par  (site web personnel) . En réponse au lien Ivre, il crée un générateur de sites statiques avec 300 lignes de python et django. Évalué à 2. Dernière modification le 05 janvier 2024 à 18:00.

    jssg propulsant galae ? :)

    en théorie, tu dois pouvoir faire des extends/block dans les .md, mais j'ai pas testé.

  • # Détails

    Posté par  (site web personnel) . En réponse au lien Scadaplayer: un outil pour visualiser sous forme de tableau de bord les données SCADA d'une éolienne. Évalué à 4. Dernière modification le 21 décembre 2023 à 19:49.

    J'voulais faire un truc rigolo avec un canvas HTML5, du vanilla typescript, et des données d'une vraie éolienne (R80711 du parc La Haute Borne de Engie)

  • [^] # Re: not new

    Posté par  (site web personnel) . En réponse au lien Découverte du théorème de Pythagore sur une tablette antérieure de 1000 ans à Pythagore. Évalué à 3.

  • [^] # Re: et moi et moi et moi…

    Posté par  (site web personnel) . En réponse au journal L'avis des daltoniens. Évalué à 4.

    anecdote rigole. Les étoiles de la 8ème colonne utilisent exactement les même couleurs que celles de la 4ème, mais grâce à la petite bordure noire, on les discrimine vachement mieux du fond. #discriminationPositive

  • # Contexte

    Posté par  (site web personnel) . En réponse au lien Workaround pour jouer à Cyberpunk 2077 Liberty Phantom sans Gog Galaxy. Évalué à 2.

    Suite a un petit foirage des devs, le DLC acheté sur GOG fait crashé le jeu au démarrage si GOG Galaxy n'est pas aussi lancé. Hors, GOG Galaxy n'est toujours pas disponible sous Linux…

    Il est à noter que la version de base du jeu marche très bien sous seule. IL semblerait que la version Steam marche aussi très bien.

    N'est concerné que le DLC acheté via GOG.

  • [^] # Re: Ça me parait léger

    Posté par  (site web personnel) . En réponse au lien Stop using Brave Browser - OSnews. Évalué à 6.

    Il est à noter que le site existait avant qu’il n’aille travailler chez Brave et qu’il n’a jamais caché cette information
    https://github.com/privacytests/privacytests.org/issues/166#issuecomment-1599996563

  • [^] # Re: actualiser..

    Posté par  (site web personnel) . En réponse au journal petit topo des messageries sécurisées, et leurs alternatives. Évalué à 5.

    j'ai crée la page et importé le journal dedans
    https://linuxfr.org/wiki/clients-de-messagerie-instanee

  • [^] # Re: Deltachat

    Posté par  (site web personnel) . En réponse au journal petit topo des messageries sécurisées, et leurs alternatives. Évalué à 3.

    mais si vous êtes tous chez gmail, je suis sûr que ça marche très bien :)

  • # Deltachat

    Posté par  (site web personnel) . En réponse au journal petit topo des messageries sécurisées, et leurs alternatives. Évalué à 10.

    Client de messagerie instantané basé sur le mail. Tu as déjà un compte email quelque part ? Félicitation, tu as un compte Deltachat. Tes amis ont une adresse email ? Félicitation, ils ont déjà un compte Deltachat. Et vu que vous êtes déjà tous sur Deltachat, autant ditcher les autres messageries :)

    Le chiffrement est assuré par autocrypt.

    https://delta.chat/

    PAR CONTRE, comme c’est basé sur le mail, ben vous aurez les mêmes emmerdes qu’avec le mail. Genre tes messages bloqués par le fournisseur de mail de ta pote parce que l’IP de ton fournisseur a fini dans une liste Spamhaus :(

  • [^] # Re: Question sérieuse : à quel degré le mot "Gimp" est-il péjoratif/offensant en anglais ?

    Posté par  (site web personnel) . En réponse au lien Une nouvelle initiative pour forker/renommer GIMP. Évalué à 6. Dernière modification le 31 juillet 2023 à 18:23.

    Est-ce que ce duo parent/enfant ne peut pas être utilisé ?

    Souvent, non.

    Parent/enfant sert plutôt à indiquer comment ils sont crées alors que master/slave indiquent leurs relation dans le traitement des données.

    Mais par chance, selon le contexte, on a d’autres paires de mots qui peuvent marcher. Notamment :

    • manager / worker
    • primary / replica, dans le cadre des serveurs de bases de données
    • jtremesay / les juniors, dans le cadre du taf (aucun de mes juniors n’a été maltraité lors de la rédaction de cette blague nulle)
  • [^] # Re: Dommage cette licence non libre

    Posté par  (site web personnel) . En réponse au journal Django + Jupyter Lab = ❤️. Évalué à 3.

    Arf, toutes mes plus plates excuses alors !

    Pas de soucis :)

    Ça n'a pas du aider la rédaction et j'aurais pu la fermer du coup. Je plaide coupable, vaut mieux écrire quand on y est disposé.

    Boarf. Au moins comme ça on a résolu le problème juridique du snippet. Parce que comme tu l'as dit, le but est avant tout que ça puisse servir à d'autre. Ça m'aurait bien fait gagner 2 semaines de prototypage si j'avais pu tomber sur mon journal quand j'ai dû dev ça pour le taf :D

  • [^] # Re: Dommage cette licence non libre

    Posté par  (site web personnel) . En réponse au journal Django + Jupyter Lab = ❤️. Évalué à 4.

    Comment dire… J’ai vu ton commentaire hier, mais je n’ai répondu qu’aujourd’hui, le temps que l’envie de te traiter de tout un tas de nom d’oiseaux redescende suffisamment.

    Car même si tu as parfaitement raison sur le fond, tout comme barmic<, j’ai trouvé la forme très violente. Sur le coup, j’ai même cru que c’était zenitram qui me répondait :-/

  • [^] # Re: Dommage cette licence non libre

    Posté par  (site web personnel) . En réponse au journal Django + Jupyter Lab = ❤️. Évalué à 2.

    Parce qu'il trouvait cette idée de licence marrante ? Que ça blague tombe à l'eau c'est une chose, mais faut souffler un peu.

    J’ai surtout lu le texte de la licence trop vite. Je pensais que c’était une MIT avec une blague en plus. Je n’avais pas réalisé que la manière dont c’était écrit ajoutait une contrainte forte et rendait le code non libre.

    Si tu veux être rigoriste s'il n'avait mis aucune licence ce serait le droit d'auteur qui s'appliquerait et qui serait ce qu'il y a de plus restrictif

    Non. Comme le journal lui même est sous licence CC BY-SA, sans mention contraire, le code inclu dans le journal aurait aussi été sous CC BY-SA. (IANAL)

  • [^] # Re: Dommage cette licence non libre

    Posté par  (site web personnel) . En réponse au journal Django + Jupyter Lab = ❤️. Évalué à 2.

    Tu as raison sur le fond. Voici le même code sous licence MIT.

    # Copyright 2023 Jonathan Tremesaygues
    #
    # Permission is hereby granted, free of charge, to any person obtaining a copy
    # of this software and associated documentation files (the "Software"), to deal
    # in the Software without restriction, including without limitation the rights
    # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    # copies of the Software, and to permit persons to whom the Software is
    # furnished to do so, subject to the following conditions:
    #
    # The above copyright notice and this permission notice shall be included in all
    # copies or substantial portions of the Software.
    #
    # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    # SOFTWARE.
    from importlib import import_module
    from typing import Awaitable, Optional
    from asgiref.sync import sync_to_async
    from jupyter_server.auth import IdentityProvider
    from jupyter_server.auth.identity import User as JUser
    from jupyter_server.base.handlers import JupyterHandler
    from django.conf import settings
    from django.contrib import auth
    from django.contrib.auth.models import User as DUser
    
    # https://jupyter-server.readthedocs.io/en/latest/operators/security.html#jupyter_server.auth.IdentityProvider
    class DjangoIdentityProvider(IdentityProvider):
        def __init__(self, **kwargs):
            super().__init__(**kwargs)
            # C'est vraiment la méthode recommandée par Django pour charqer le bon
            # moteur de session >_<
            # https://docs.djangoproject.com/en/4.2/topics/http/sessions/#using-sessions-out-of-views
            self.SessionStore = import_module(settings.SESSION_ENGINE).SessionStore
    
        # https://jupyter-server.readthedocs.io/en/latest/operators/security.html#jupyter_server.auth.IdentityProvider.get_user
        async def get_user(self, handler: JupyterHandler) -> Optional[JUser] | Awaitable[Optional[JUser]]:
            # `get_user` est utilisé dans un contexte async mais Django préfère un 
            # contexte sync pour parler avec la db. Et le SessionStore par défaut 
            # utilise la db. Pis de toute façon faudra accéder à la DB pour charger
            # l'utilisateur.
            # https://docs.djangoproject.com/en/4.2/topics/async/
            return await sync_to_async(self._get_user)(handler)
    
        def _get_user(self, handler: JupyterHandler) -> Optional[JUser]:
            # Essaye de récupérer le session id dans les cookies
            if (cookie_entry := handler.request.cookies.get(settings.SESSION_COOKIE_NAME)) is not None:
                # Charge la session correspondante
                session = self.SessionStore(session_key=cookie_entry.value).load()
    
                # Essaye de récupérer l'user id correspondant
                if (user_id := session[auth.SESSION_KEY]) is not None:
                    try:
                        # Essaye de charger l'utilisateur correspondant 
                        user = DUser.objects.get(pk=user_id)
                    except DUser.DoesNotExist:
                        # Utilisateur non trouvé
                        pass
                    else:
                        # Est-ce que l'utilisateur est un admin?
                        if user.is_staff:
                            # L'utilisateur actuel est bien connecté et est un admin!
                            # Crée un Jupyter user à partir du Django user
                            return JUser(username=user.username)
    
            # Impossible d'authentifier l'utilisateur
            return None
  • [^] # Re: Je ne sais pas trop comment j’ai foiré ma veille technologique à ce point,

    Posté par  (site web personnel) . En réponse au lien NGINX Universal Web App Server. Évalué à 3.

    Il n’a pas l’air d’avoir une configuration dynamique des vhosts basé sur les labels docker, qui est la raison pour laquelle j’avais ditché nginx en faveur de traefik.

    Exemple avec traefik:

    services:
    
      traefik:
        image: "traefik:v2.10"
        container_name: "traefik"
        ports:
          - "80:80"
        volumes:
          - "/var/run/docker.sock:/var/run/docker.sock:ro"
    
      whoami:
        image: "traefik/whoami"
        labels:
          - "traefik.enable=true"
          - "traefik.http.routers.whoami.rule=Host(`whoami.jtremesay.org`)"

    Exemple avec nginx-proxy:

    services:
      nginx-proxy:
        image: nginxproxy/nginx-proxy
        ports:
          - "80:80"
        volumes:
          - /var/run/docker.sock:/tmp/docker.sock:ro
    
      whoami:
        image: "traefik/whoami"
        expose:
          - "8000"
        environment:
          - VIRTUAL_HOST=whoami.jtremesay.org
          - VIRTUAL_PORT=8000
  • [^] # Re: Je ne sais pas trop comment j’ai foiré ma veille technologique à ce point,

    Posté par  (site web personnel) . En réponse au lien NGINX Universal Web App Server. Évalué à 2.

    Je découvre aussi nginx-proxy et acme-companion
    https://github.com/nginx-proxy/acme-companion
    https://github.com/nginx-proxy/nginx-proxy

    Qui me permettraient de remplacer traefik dans mes stacks. Pas que j'aime pas traefik, il fait le taf. Mais je suis sentimentalement attaché à nginx, et je suis triste d'avoir arrêté de l'utilisé parce que moins pertinant dans mes stacks cloud.

  • # Précision sur les notebook

    Posté par  (site web personnel) . En réponse au journal Django + Jupyter Lab = ❤️. Évalué à 6.

    Il faut utiliser le kernel "Django Shell-Plus" pour exécuter vos notebooks.

    De plus, le notebook est exécuté dans un contexte asynchrone. Ce qui rend relou la réutilisation de ton vieux code synchrone.

    Si tu ne veux pas te prendre la tête, voila un boilerplate à utiliser dans le notebook pour simplifier tout ça :

    from asgiref.sync import sync_to_async
    from django.contrib.auth.models import User
    
    @sync_to_async
    def main():
        # Ton code synchrone ici
        print(User.objects.all())
    
    await main()

    Tu peux aussi utiliser Numpy et matplotlib pour faire de jolis graphs.