<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>dece</title>
    <link>https://textes.pistache.land/dece/</link>
    <description></description>
    <pubDate>Fri, 08 May 2026 12:11:30 +0200</pubDate>
    <item>
      <title>Créer une API Web pour interagir avec Sage 100</title>
      <link>https://textes.pistache.land/dece/creer-une-api-web-pour-interagir-avec-sage-100</link>
      <description>&lt;![CDATA[Mon association utilise Sage 100 pour sa comptabilité et sa gestion commerciale. On avait le projet de permettre d&#39;adhérer par HelloAsso tout en gardant Sage comme le registre officiel, donc avec un moyen pour nous de mettre à jour des données d&#39;adhérents sur Sage suite à une adhésion sur HelloAsso. Mais voilà, il n&#39;y a pas d&#39;API Sage qui permettrait de faire ça, à part quelques services propriétaires et payants. La seule méthode officielle pour interagir avec Sage est de créer des applications Windows utilisant la bibliothèque « objets métiers », c&#39;est à dire une DLL avec des entrées COM dessus, bien années 2000, attendez je vais chercher ma Beyblade ! !--more--&#xA;&#xA;La solution que j&#39;ai trouvé c&#39;est de développer deux API : Passage, une API en C# collée à Sage utilisant les objets métiers dont je vais parler ici, et un module de notre intranet maison pour faire le lien entre HelloAsso et Passage sur lequel je passerai brièvement.&#xA;&#xA;Le but de cet article hautement spécifique est de faire gagner du temps à des structures comme la mienne qui se retrouvent un peu perdues face à la boîte noire qu&#39;est Sage lorsqu&#39;il faut interagir avec ses données, en présentant le cheminement que j&#39;ai suivi pour atteindre mes objectifs.&#xA;&#xA;À noter : je me concentre sur mon cas d&#39;usage qui est une interaction avec un Sage 100 on-premise, c&#39;est à dire installé sur un serveur à nous, je ne sais pas du tout comment fonctionne les versions cloud de Sage. Il s&#39;agit aussi de la version française de Sage 100 qui est assez différente de la version internationale, donc traduire ses recherches pour avoir des résultats internationaux n&#39;est pas forcément judicieux.&#xA;&#xA;Sur l&#39;absence de documentation sur le Web&#xA;&#xA;Sage ne diffuse que peu de documentation sur le Web sur comment développer une application utilisant ses objets métiers, parce qu&#39;ils vendent des formations à 720€ les 3 demi-journées, ce qui est un peu trop prohibitif à mon goût vu ce qu&#39;on paye déjà en licences logicielles. Il va donc falloir sortir ses meilleures requêtes sur votre moteur de recherche de prédilection pour trouver les obscurs messages de forum datant d&#39;il y a 15 ans qui vous permettront de surmonter tel ou tel obstacle. Si vous avez un prestataire qui gère votre installation Sage, c&#39;est possible de lui demander quelques conseils mais il risque de vous diriger rapidement vers le site de formation ou de vouloir vous facturer une intervention.&#xA;&#xA;J&#39;ai quand même trouvé pas mal d&#39;infos dans deux documents que je vous link ci-dessous (attention c&#39;est pour Sage v9). Le premier est la doc&#39; des objets métiers qui présente les principes d&#39;utilisation avec quelques exemples de cas d&#39;usage, pour la plupart en Visual Basic, parfois en C#. C&#39;est très superficiel mais il y a quand même pas mal d&#39;infos bonnes à prendre. J&#39;ai appris l&#39;existence du second par des messages cryptiques de forum expliquant qu&#39;il fallait se référer au « strucfic » pour comprendre l&#39;organisation de la base de données. Le quoi ?! Arrêtez d&#39;inventer des mots, il y a déjà assez d&#39;information à intégrer. En fait c&#39;est le petit nom du document « Structure des fichiers », qui décrit en détail l&#39;organisation de la base de données SQL utilisée par Sage et sur laquelle on reviendra plus tard.&#xA;&#xA;PDF Objets métiers&#xA;PDF Structure des fichiers&#xA;&#xA;Je vous conseille de survoler au moins le premier document, et de garder le deuxième sous le coude pour plus tard.&#xA;&#xA;## Créer un projet C# avec les objets métiers Sage&#xA;&#xA;Le langage le plus représenté dans les exemples qu&#39;on peut trouver en ligne c&#39;est du Visual Basic, mais je n&#39;avais vraiment pas envie d&#39;introduire ce langage dans notre stack. Mon association utilise du PHP partout mais il n&#39;y a aucune documentation officielle ou pas sur l&#39;utilisation des objets métiers via l&#39;extension COM de PHP donc je me suis orienté vers la moins pire des alternatives, C#, pour développer Passage.&#xA;&#xA;C&#39;est important de noter que je n&#39;y connaissais presque rien en C# mais ça ne m&#39;a trop gêné, les tutoriels sur le MSDN étant corrects, si on les consulte en anglais car les traductions françaises sont automatisées et régulièrement catastrophiques.&#xA;&#xA;Préparation&#xA;&#xA;Le système de licence Sage étant ce qu&#39;il est, le plus simple est probablement de travailler directement sur le serveur où est installé Sage, mais organisez-vous comme ça vous semble le mieux.&#xA;&#xA;Préparez votre environnement de développement C# avec Visual Studio, installez les objets métiers (installeur ci-dessous), créez une base de données de test sur SQL Server—votre prestataire Sage doit pouvoir vous aider ici, moi j&#39;ai dupliqué notre base de production pour pouvoir tester des trucs sur des données réalistes sans toucher aux données de production.&#xA;&#xA;Téléchargez l&#39;installeur objets métiers par ici.&#xA;&#xA;Le projet de base&#xA;&#xA;Je vais être très synthétique ici, j&#39;ai suivi les tutoriels pour créer une API Web avec ASP.NET Core. Je ne comprends rien au mille dénominations de technos Web chez Microsoft, mais ça avait l&#39;air d&#39;être le truc moderne fin 2023 sur lequel aller. Je vous laisse explorer le MSDN pour la création de projet et les principes du framework.&#xA;&#xA;Créer une API Web avec ASP.NET Core&#xA;&#xA;À un moment vous allez devoir ajouter les objets métiers Sage comme dépendances à votre projet. Je ne me rappelle plus comment j&#39;ai fait dans le mille-feuilles de menus et d&#39;options sur Visual Studio, il faut ajouter une « référence COM » quelque part et vous trouvez les objets métiers Sage dans une immense liste… Là aussi, les moteurs de recherches sont vos meilleurs alliés. Je sais juste qu&#39;à force d&#39;essayer je me suis retrouvé avec cette section dans mon fichier de projet Passage.csproj :&#xA;&#xA;  ItemGroup&#xA;    COMReference Include=&#34;Objets100cLib&#34;&#xA;      WrapperTooltlbimp/WrapperTool&#xA;      VersionMinor2/VersionMinor&#xA;      VersionMajor9/VersionMajor&#xA;      Guid8b42efd1-11de-4af5-8f95-2901702d7a46/Guid&#xA;      Lcid0/Lcid&#xA;      Isolatedfalse/Isolated&#xA;      EmbedInteropTypestrue/EmbedInteropTypes&#xA;    /COMReference&#xA;  /ItemGroup&#xA;&#xA;Vous êtes prêt lorsque vous avez une petite API qui tourne avec, disons, un ApiController de test que vous pouvez interroger, si possible le Swagger d&#39;activé pour tester vos endpoints et que vous pouvez importer les objets métiers Sage dans votre code :&#xA;&#xA;using Objets100cLib;&#xA;&#xA;Lire des infos contenues dans Sage via SQL&#xA;&#xA;J&#39;en ai pas parlé jusqu&#39;ici mais c&#39;est importer de savoir qu&#39;on peut lire l&#39;intégralité du contenu stocké dans Sage sans toucher à Sage ni aux objets métiers mais simplement en lisant la base de données SQL Server&amp;nbsp;! Les données sont réparties sur beaucoup de tables que le PDF structure des fichiers documente copieusement. Par exemple la table FDOCENTETE contient tous les entêtes de document dont les factures, FDOCLIGNE contient chaque ligne de facture, FARTICLE les articles, FCOMPTET les comptes tiers et leurs champs d&#39;informations libres, etc. &#xA;&#xA;Dans la pratique, j&#39;ai trouvé que c&#39;était souvent plus simple de faire une bonne grosse requête SQL directement sur la base plutôt que de s&#39;embêter avec l&#39;API des objets métiers pour créer des collections et galérer à filtrer les résultats.&#xA;&#xA;Exemple de requête pour trouver les numéros de compte tiers avec une adresse e-mail donnée :&#xA;&#xA;SELECT CTNum&#xA;FROM FCOMPTET&#xA;WHERE CTEMail = &#39;client@example.com&#39;&#xA;&#xA;Ou encore vérifier qu&#39;une référence de facture existe :&#xA;&#xA;SELECT DORef&#xA;FROM FDOCLIGNE&#xA;WHERE DORef = &#39;REF549832&#39;&#xA;&#xA;Se connecter à Sage avec les objets métiers&#xA;&#xA;Mais alors attends, pourquoi se prendre la tête avec des objets métiers si on peut taper directement dans la base de données ? Parce qu&#39;il y a beaucoup de triggers et de colonnes obscures qui sont compliquées à mettre à jour à la main et vous risquez de corrompre votre Sage si vous les modifiez vous-même. Autant pour la lecture il n&#39;y a pas de problème, autant je ne me risquerai pas à exécuter le moindre INSERT ou UPDATE sur les tables de Sage.&#xA;&#xA;Avant de passer à la phase modification, on va donc regarder comment utiliser les objets métiers pour se connecter à Sage.&#xA;&#xA;Ouvrir et fermer une connexion&#xA;&#xA;Selon l&#39;offre de Sage qu&#39;on a, on peut avoir plusieurs module auxquels se connecter. Ici on a la comptabilité et la gestion commerciale, et ça fait deux modules auxquels on peut se connecter via deux objets différents dans l&#39;API des objets métiers. La base compta est gérée via l&#39;objet BSCPTAApplication100c et la base gestion commerciale (que je vais abréger en gescom) est gérée via l&#39;objet BSCIALApplication100c. On ouvre et referme la connexion à ces deux objets avec une même interface, mais les deux objets permettent ensuite d&#39;accéder à différentes parties de Sage. Par exemple on manipule les comptes tiers avec la base compta mais on manipule les documents de vente avec la base gescom.&#xA;&#xA;Le code suivant permet d&#39;ouvrir une connexion à chacune des deux bases puis de les refermer :&#xA;&#xA;using Objets100cLib;&#xA;&#xA;namespace Passage&#xA;{&#xA;    internal class Sage&#xA;    {&#xA;        public static readonly string Server = @&#34;MON-SERVEUR\SAGE100&#34;;&#xA;        public static readonly string Database = &#34;MA-BASE-DE-TEST&#34;;&#xA;        public static readonly string User = &#34;MON-USER&#34;;&#xA;        public static readonly string Password = &#34;MON-MDP&#34;;&#xA;&#xA;        public static void DemoConnexion()&#xA;        {&#xA;            // Ouverture de la base Comptabilité.&#xA;            var cpta = new BSCPTAApplication100c();&#xA;            cpta.CompanyServer = Server;&#xA;            cpta.CompanyDatabaseName = Database;&#xA;            cpta.Loggable.UserName = User;&#xA;            cpta.Loggable.UserPwd = Password;&#xA;            cpta.Open();&#xA;            if (cpta.IsOpen)&#xA;            {&#xA;                Console.WriteLine(&#34;Connecté à la base compta.&#34;);&#xA;                // Ici on peut interagir avec la base compta, par exemple :&#xA;                //   cpta.FactoryClient.ReadNumero(...)&#xA;                // Et on la referme après utilisation.&#xA;                cpta.Close();&#xA;            }&#xA;            else&#xA;            {&#xA;                Console.WriteLine(&#34;Échec de l&#39;ouverture de la base compta.&#34;);&#xA;            }&#xA;&#xA;            // Ouverture de la base Gestion Commerciale.&#xA;            var cial = new BSCIALApplication100c();&#xA;            cial.CompanyServer = Server;&#xA;            cial.CompanyDatabaseName = Database;&#xA;            cial.Loggable.UserName = User;&#xA;            cial.Loggable.UserPwd = Password;&#xA;            cial.Open();&#xA;            if (cial.IsOpen)&#xA;            {&#xA;                Console.WriteLine(&#34;Connecté à la base gescom.&#34;);&#xA;                // Ici on peut interagir avec la base commerciale, par exemple :&#xA;                //   cial.CreateProcessDocument(DocumentType.DocumentTypeVenteCommande)&#xA;                // Et on la referme après utilisation.&#xA;                cial.Close();&#xA;            }&#xA;            else&#xA;            {&#xA;                Console.WriteLine(&#34;Échec de l&#39;ouverture de la base gescom.&#34;);&#xA;            }&#xA;        }&#xA;    }&#xA;}&#xA;&#xA;Dans certains cas vous serez amené à devoir utiliser les deux bases en simultané et à leur permettre d&#39;interagir entre elle, en mettant la base compta à l&#39;attribut CptaApplication de la base gescom, sous peine de vous prendre des erreurs comme quoi une des deux bases est inaccessible :&#xA;&#xA;cial.CptaApplication = cpta;&#xA;&#xA;Récupérer un objet et ses propriétés&#xA;&#xA;Pour vérifier que vous pouvez lire les infos depuis la base compta vous pouvez essayer de lire les infos d&#39;un client, par exemple le client n°1000 :&#xA;&#xA;if (cpta.FactoryClient.ExistNumero(1000))&#xA;    objClient = cpta.FactoryClient.ReadNumero(1000);&#xA;if (objClient == null)&#xA;    return;&#xA;&#xA;Console.WriteLine($&#34;Intitulé du compte 1000 : {objClient.CTIntitule}&#34;);&#xA;&#xA;Pour vérifier que vous pouvez lire les infos depuis la base gescom vous pouvez essayer de lire les infos d&#39;un article, par exemple le prix d&#39;achat de l&#39;article qui porte la référence « BOOK1312 » :&#xA;&#xA;if (!cial.FactoryArticle.ExistReference(&#34;BOOK1312&#34;))&#xA;    return AdhesionResult.Result.ARTICLENOTFOUND;&#xA;IBOArticle3 article = cial.FactoryArticle.ReadReference(&#34;BOOK1312&#34;);&#xA;double prixAchat = article.ARPrixAchat;&#xA;&#xA;Euh CTIntitule ? ARPrixAchat ? Et ça sort d&#39;où ces commandes ExistNumero, ReadReference ? Tout est dans le PDF objets métiers !&#xA;&#xA;Dans la suite de l&#39;article je ne recopie pas toutes ces lignes, mais toute manipulation en lecture et en écriture avec les objets métiers doit se faire avec la ou les bonnes connexions ouvertes. C&#39;est relativement rapide donc à moins d&#39;un gros flux de requêtes ça n&#39;a pas l&#39;air de poser problème d&#39;ouvrir et fermer la connexion à chaque opération.&#xA;&#xA;Récupérer un ensemble d&#39;objets&#xA;&#xA;Je ne vais pas rentrer dans les détails ici mais la plupart des objets qui peuvent se lister ont une classe associée nommée Factory, e.g. IBOArticleFactory3, qui renvoient des collections, et ces objets peuvent être énumérés. Là encore il y a des explications succinctes mais suffisantes dans les PDF. Comme expliqué plus haut, je trouve que l&#39;interface est trop limitée par rapport à une requête SQL, mais peut-être que je n&#39;ai juste pas passé assez de temps à essayer d&#39;arriver à mes fins avec leur API.&#xA;&#xA;Modifier des infos contenues dans Sage&#xA;&#xA;On va donc voir ici comment utiliser les objets métiers pour ça. Si c&#39;est pas déjà fait, je vous conseille de parcourir le PDF objets métiers car je vais me concentrer sur des exemples d&#39;utilisation concrets et qu&#39;il y a des concepts expliqués à ne pas louper comme la persistance des données, les champs par défaut de certains objets lors de leur création, etc. Cela dit, le PDF n&#39;est pas toujours très précis et il vaut mieux faire ses tests ponctués de Console.WriteLine pour s&#39;assurer qu&#39;on a bien tout compris.&#xA;&#xA;Exemple simple : changer l&#39;intitulé d&#39;un client&#xA;&#xA;On chope l&#39;objet client qui porte le numéro 123 et on met son intitulé de compte (nom de société, nom prénom, etc) en majuscules. Oui c&#39;est nul mais c&#39;est pour la démo :&#xA;&#xA;// 1) On récupère l&#39;objet client.&#xA;if (cpta.FactoryClient.ExistNumero(123))&#xA;    client = cpta.FactoryClient.ReadNumero(123);&#xA;if (client == null)&#xA;    return;&#xA;// 2) On fait notre traitement, on change l&#39;attribut qui va bien.&#xA;string nom = client.CTIntitule;&#xA;nom = nom.ToUpper();&#xA;client.CTIntitule = nom;&#xA;// 3) On sauvegarde nos changements.&#xA;client.Write();&#xA;&#xA;Ce qu&#39;il faut noter ici c&#39;est qu&#39;on peut lire et écrire les attributs de nos objets métiers comme on veut, mais que les modifications ne sont pas enregistrés en base de données tant qu&#39;on n&#39;a pas utilisé Write() (ou WriteDefault()). C&#39;est seulement après cet appel que les modifications sont écrites en base de données. La validation des données—la taille des strings, des valeurs autorisées ou non, etc—se fait à deux endroits, parfois à l&#39;assignation d&#39;une valeur dans un champ, et parfois au moment de l&#39;écriture, et c&#39;est pourquoi il vaut mieux englober toute ses manipulation dans des gros blocs de capture d&#39;exception parce que ça peut péter à de multiples endroits.&#xA;&#xA;Exemple un peu moins simple : changer tout un tas d&#39;infos client&#xA;&#xA;Pareil que l&#39;exemple précédent mais avec plus de modifications. On imagine un objet adhesion qui contiendrait les infos fournies par une API externe sur une nouvelle adhésion, et qu&#39;on voudrait utiliser pour mettre à jour les infos de nos comptes clients.&#xA;&#xA;Notez ici l&#39;existence de l&#39;objet client.LivraisonPrincipal, de type IBOClientLivraison3, et qu&#39;on met à jour en simultané de notre objet client. Dans les deux cas, les infos d&#39;adresse sont dans un sous-objet astucieusement nommé Adresse.&#xA;&#xA;// On remplace tout un tas de champ par ceux de notre objet adhésion.&#xA;// Notez comment on tronque certaines chaînes, car elles peuvent avoir&#xA;// une limite de taille (pas toujours clairement précisée d&#39;ailleurs…)&#xA;client.CTIntitule = adhesion.FullName;&#xA;client.CTClassement = Utilities.Truncate(adhesion.FullName, 17);&#xA;client.CTContact = adhesion.FullName;&#xA;client.LivraisonPrincipal.LIContact = adhesion.FullName;&#xA;client.LivraisonPrincipal.LIIntitule = adhesion.FullName;&#xA;&#xA;address = Utilities.Truncate(adhesion.Address, 35).ToUpper();&#xA;client.Adresse.Adresse = address;&#xA;client.Adresse.Complement = &#34;&#34;;&#xA;client.LivraisonPrincipal.Adresse.Adresse = address;&#xA;client.LivraisonPrincipal.Adresse.Complement = &#34;&#34;;&#xA;&#xA;zipCode = Utilities.Truncate(adhesion.ZipCode, 9).ToUpper();&#xA;client.Adresse.CodePostal = zipCode;&#xA;client.LivraisonPrincipal.Adresse.CodePostal = zipCode;&#xA;&#xA;city = Utilities.Truncate(adhesion.City, 35).ToUpper();&#xA;client.Adresse.Ville = city;&#xA;client.LivraisonPrincipal.Adresse.Ville = city;&#xA;&#xA;payerCountry = Utilities.Truncate(adhesion.PayerCountry, 35).ToUpper();&#xA;client.Adresse.Pays = payerCountry;&#xA;client.LivraisonPrincipal.Adresse.Pays = payerCountry;&#xA;&#xA;phone = Utilities.Truncate(adhesion.phone, 21);&#xA;client.Telecom.Telephone = phone;&#xA;client.LivraisonPrincipal.Telecom.Telephone = phone;&#xA;&#xA;// On met à jour un champ d&#39;information libre, identifié par son nom dans Sage.&#xA;// Attention à bien utiliser le bon type, SSMS peut être utile ici&#xA;// pour récupérer le type de la colonne correspondante.&#xA;DateTime dateTime = Utilities.ParseRfc3339(adhesion.Date) ?? DateTime.Now;&#xA;client.InfoLibre[&#34;Dernière année d&#39;adhésion&#34;] = dateTime.Year.ToString();&#xA;&#xA;// On écrit l&#39;objet client mais aussi l&#39;objet LivraisonPrincipal.&#xA;// Pas sûr que ça soit super utile mais j&#39;ai pas bien compris&#xA;// à quel point les objets s&#39;écrivaient en cascade ou pas,&#xA;// et ça ne coute pas grand chose de toute façon.&#xA;client.Write();&#xA;client.LivraisonPrincipal.Write();&#xA;&#xA;Exemple avancé : créer une facture&#xA;&#xA;Dans ce dernier exemple, je vais créer une facture et l&#39;enregistrer. On utilise un objet un peu particulier, le résultat de CreateProcessDocument, qui émule les actions qu&#39;un utilisateur pourrait avoir en utilisant l&#39;interface graphique de Sage (son « processus », d&#39;où le nom de &#34;process&#34;).&#xA;&#xA;// On va créer une facture pour un article avec cette référence et cette gamme.&#xA;string refArticle = &#34;BOOK1312&#34;;&#xA;string refGamme = &#34;Collector&#34;;&#xA;&#xA;// On crée le process. On va interagir à la fois avec cet objet,&#xA;// et aussi avec l&#39;objet IBODocumentVente3 qu&#39;il contient.&#xA;DocumentType docType = DocumentType.DocumentTypeVenteCommande;&#xA;IPMDocument process = cial.CreateProcessDocument(docType);&#xA;IBODocumentVente3 facture = (IBODocumentVente3)process.Document;&#xA;// On commence par écrire les attributs par défaut :&#xA;facture.SetDefault();&#xA;// On attribue un objet client récupéré plus tôt :&#xA;facture.SetDefaultClient(client);&#xA;// On attribue un numéro de pièce :&#xA;facture.SetDefaultDOPiece();&#xA;// On modifie quelques attributs supplémentaires selon nos besoins :&#xA;facture.LieuLivraison = client.LivraisonPrincipal;&#xA;facture.DepotStockage = cial.FactoryDepot.ReadIntitule(adhesion.Depot);&#xA;facture.DONoWeb = &#34;CMD123456&#34;;&#xA;facture.DORef = &#34;XX123456&#34;;&#xA;facture.DODate = dateTime; // objet de type DateTime&#xA;&#xA;// Est-ce l&#39;article demandé existe bien ?&#xA;if (!cial.FactoryArticle.ExistReference(refArticle))&#xA;    return &#34;ARTICLENOTFOUND&#34;;&#xA;IBOArticle3 article = cial.FactoryArticle.ReadReference(refArticle);&#xA;&#xA;// Est-ce que la gamme de l&#39;article demandée existe bien ?&#xA;if (!article.FactoryArticleGammeEnum1.ExistEnumere(refGammeType))&#xA;    return &#34;GAMMENOTFOUND&#34;;&#xA;IBOArticleGammeEnum3 gammeType = article.FactoryArticleGammeEnum1.ReadEnumere(refGammeType);&#xA;&#xA;// On ajoute notre ligne de facture avec un article en utilisant sa gamme.&#xA;// Voir également dans les docs : AddArticle, AddArticleDoubleGamme.&#xA;process.AddArticleMonoGamme(gammeType, 1);&#xA;&#xA;// Création de l&#39;acompte.&#xA;// Bon là je fais n&#39;importe quoi, c&#39;est pour l&#39;exemple.&#xA;if (adhesion.ItemAmount   0)&#xA;{&#xA;    IBODocumentAcompte3 acompte = (IBODocumentAcompte3)facture.FactoryDocumentAcompte.Create();&#xA;    acompte.SetDefault();&#xA;    acompte.DRDate = dateTime;&#xA;    acompte.DRMontant = ((double)amount) / 100; // attention aux types…&#xA;    // Je mets le bon réglement…&#xA;    if (!acompte.Reglement.FactoryReglement.ExistIntitule(&#34;ABC&#34;))&#xA;        return &#34;REGLEMENTNOTFOUND&#34;;&#xA;    acompte.Reglement = acompte.Reglement.FactoryReglement.ReadIntitule(&#34;ABC&#34;);&#xA;    // Je mets le bon code journal pour l&#39;acompte…&#xA;    if (!cpta.FactoryJournal.ExistNumero(&#34;DEF&#34;))&#xA;        return &#34;CODEJOURNALNOTFOUND&#34;;&#xA;    acompte.Reglement.JournalClient = cpta.FactoryJournal.ReadNumero(&#34;DEF&#34;);&#xA;    // Enfin, je n&#39;oublie pas d&#39;écrire mon objet d&#39;acompte.&#xA;    acompte.Write();&#xA;}&#xA;&#xA;// L&#39;objet process a un attribut qui permet de vérifier&#xA;// s&#39;il n&#39;y a pas d&#39;erreur à la création.&#xA;if (!process.CanProcess)&#xA;{&#xA;    foreach (IFailInfo error in process.Errors)&#xA;    {&#xA;        Logger.LogError(&#xA;            &#34;Impossible de créer le document : {n} {text}&#34;,&#xA;            error.Indice,&#xA;            error.Text&#xA;        );&#xA;    }&#xA;    return &#34;CANTCREATEDOCUMENT&#34;;&#xA;}&#xA;Logger.LogInformation(&#34;Document prêt pour création.&#34;);&#xA;&#xA;// Enfin, on enregistre les objets.&#xA;process.Process();&#xA;Logger.LogInformation(&#34;Document créé.&#34;);&#xA;client.Write();&#xA;client.LivraisonPrincipal.Write();&#xA;Logger.LogInformation(&#34;Compte client et adresse de livraison principale mis à jour.&#34;);&#xA;&#xA;Si tout se passe bien, on se retrouve avec un bon de commande dans Sage que l&#39;on peut ensuite passer en facture comptabilisée à la main.&#xA;&#xA;Conclusion&#xA;&#xA;L&#39;autre API dont je n&#39;ai pas parlé, notre module d&#39;intranet, permet de récupérer les infos d&#39;adhésion depuis HelloAsso et de les traiter avec une file de messages, avec une interface graphique sympa, une base de données PostgreSQL, et tout un tas de choses que je maîtrise bien mieux qu&#39;une API en C# sur un serveur Windows derrière N firewalls et un VPN. C&#39;est vachement plus simple de gérer les notifications en provenance de HelloAsso depuis ce module que depuis Passage, qui peut donc ne contenir que du code en rapport avec la base SQL ou les objets métiers et des contrôleurs les plus légers possible.&#xA;&#xA;J&#39;espère que cet article sera utile parce que j&#39;ai passé pas mal de temps à m&#39;y retrouver dans cet écosystème hostile. N&#39;hésitez pas à m&#39;écrire si vous avez besoin d&#39;un coup de main, je ne garantis pas de pouvoir répondre rapidement mais j&#39;essayerai et je pourrai compléter cet article en conséquence.&#xA;&#xA;backfromthecodemines]]&gt;</description>
      <content:encoded><![CDATA[<p>Mon association utilise <a href="https://www.sage.com/fr-fr/produits/sage-100/" rel="nofollow">Sage 100</a> pour sa comptabilité et sa gestion commerciale. On avait le projet de permettre d&#39;adhérer par <a href="https://www.helloasso.com/" rel="nofollow">HelloAsso</a> tout en gardant Sage comme le registre officiel, donc avec un moyen pour nous de mettre à jour des données d&#39;adhérents sur Sage suite à une adhésion sur HelloAsso. Mais voilà, il n&#39;y a pas d&#39;API Sage qui permettrait de faire ça, à part quelques services propriétaires et payants. La seule méthode officielle pour interagir avec Sage est de créer des applications Windows utilisant la bibliothèque « objets métiers », c&#39;est à dire une DLL avec des entrées COM dessus, bien années 2000, attendez je vais chercher ma <a href="https://www.youtube.com/watch?v=PhlHrRzNvRo" rel="nofollow">Beyblade</a> ! </p>

<p>La solution que j&#39;ai trouvé c&#39;est de développer deux API : <em>Passage</em>, une API en C# collée à Sage utilisant les objets métiers dont je vais parler ici, et un module de notre intranet maison pour faire le lien entre HelloAsso et Passage sur lequel je passerai brièvement.</p>

<p>Le but de cet article hautement spécifique est de faire gagner du temps à des structures comme la mienne qui se retrouvent un peu perdues face à la boîte noire qu&#39;est Sage lorsqu&#39;il faut interagir avec ses données, en présentant le cheminement que j&#39;ai suivi pour atteindre mes objectifs.</p>

<p>À noter : je me concentre sur mon cas d&#39;usage qui est une interaction avec un Sage 100 <em>on-premise</em>, c&#39;est à dire installé sur un serveur à nous, je ne sais pas du tout comment fonctionne les versions <em>cloud</em> de Sage. Il s&#39;agit aussi de la version française de Sage 100 qui est assez différente de la version internationale, donc traduire ses recherches pour avoir des résultats internationaux n&#39;est pas forcément judicieux.</p>

<h2 id="sur-l-absence-de-documentation-sur-le-web" id="sur-l-absence-de-documentation-sur-le-web">Sur l&#39;absence de documentation sur le Web</h2>

<p>Sage ne diffuse que peu de documentation sur le Web sur comment développer une application utilisant ses objets métiers, parce qu&#39;ils vendent <a href="https://sageu.csod.com/ui/lms-learning-details/app/event/d4b24b5b-6360-46a4-b287-59a3f48174b1" rel="nofollow">des formations à 720€ les 3 demi-journées</a>, ce qui est un peu trop prohibitif à mon goût vu ce qu&#39;on paye déjà en licences logicielles. Il va donc falloir sortir ses meilleures requêtes sur votre moteur de recherche de prédilection pour trouver les obscurs messages de forum datant d&#39;il y a 15 ans qui vous permettront de surmonter tel ou tel obstacle. Si vous avez un prestataire qui gère votre installation Sage, c&#39;est possible de lui demander quelques conseils mais il risque de vous diriger rapidement vers le site de formation ou de vouloir vous facturer une intervention.</p>

<p>J&#39;ai quand même trouvé pas mal d&#39;infos dans deux documents que je vous link ci-dessous (attention c&#39;est pour Sage v9). Le premier est la doc&#39; des objets métiers qui présente les principes d&#39;utilisation avec quelques exemples de cas d&#39;usage, pour la plupart en Visual Basic, parfois en C#. C&#39;est très superficiel mais il y a quand même pas mal d&#39;infos bonnes à prendre. J&#39;ai appris l&#39;existence du second par des messages cryptiques de forum expliquant qu&#39;il fallait se référer au « strucfic » pour comprendre l&#39;organisation de la base de données. Le quoi ?! Arrêtez d&#39;inventer des mots, il y a déjà assez d&#39;information à intégrer. En fait c&#39;est le petit nom du document « Structure des fichiers », qui décrit en détail l&#39;organisation de la base de données SQL utilisée par Sage et sur laquelle on reviendra plus tard.</p>
<ul><li><a href="https://files.dece.space/docs/sage/sage%20100c%20objets%20m%C3%A9tiers.pdf" rel="nofollow">PDF Objets métiers</a></li>
<li><a href="https://files.dece.space/docs/sage/Sage%20100c%20v9.00%20-%20Structure%20des%20fichiers.pdf" rel="nofollow">PDF Structure des fichiers</a></li></ul>

<p>Je vous conseille de survoler au moins le premier document, et de garder le deuxième sous le coude pour plus tard.</p>

<h2 id="créer-un-projet-c-avec-les-objets-métiers-sage" id="créer-un-projet-c-avec-les-objets-métiers-sage">Créer un projet C# avec les objets métiers Sage</h2>

<p>Le langage le plus représenté dans les exemples qu&#39;on peut trouver en ligne c&#39;est du Visual Basic, mais je n&#39;avais vraiment pas envie d&#39;introduire ce langage dans notre stack. Mon association utilise du PHP partout mais il n&#39;y a aucune documentation officielle ou pas sur l&#39;utilisation des objets métiers via l&#39;extension COM de PHP donc je me suis orienté vers la moins pire des alternatives, C#, pour développer Passage.</p>

<p>C&#39;est important de noter que je n&#39;y connaissais presque rien en C# mais ça ne m&#39;a trop gêné, les tutoriels sur le MSDN étant corrects, si on les consulte en anglais car les traductions françaises sont automatisées et régulièrement catastrophiques.</p>

<h3 id="préparation" id="préparation">Préparation</h3>

<p>Le système de licence Sage étant ce qu&#39;il est, le plus simple est probablement de travailler directement sur le serveur où est installé Sage, mais organisez-vous comme ça vous semble le mieux.</p>

<p>Préparez votre environnement de développement C# avec Visual Studio, installez les objets métiers (installeur ci-dessous), créez une base de données de test sur SQL Server—votre prestataire Sage doit pouvoir vous aider ici, moi j&#39;ai dupliqué notre base de production pour pouvoir tester des trucs sur des données réalistes sans toucher aux données de production.</p>

<p><a href="https://fr-kb.sage.com/portal/app/portlets/results/viewsolution.jsp?solutionid=211010150079696" rel="nofollow">Téléchargez l&#39;installeur objets métiers par ici</a>.</p>

<h3 id="le-projet-de-base" id="le-projet-de-base">Le projet de base</h3>

<p>Je vais être très synthétique ici, j&#39;ai suivi les tutoriels pour créer une API Web avec ASP.NET Core. Je ne comprends rien au mille dénominations de technos Web chez Microsoft, mais ça avait l&#39;air d&#39;être le truc moderne fin 2023 sur lequel aller. Je vous laisse explorer le MSDN pour la création de projet et les principes du framework.</p>

<p><a href="https://learn.microsoft.com/en-us/aspnet/core/tutorials/first-web-api?view=aspnetcore-8.0&amp;tabs=visual-studio" rel="nofollow">Créer une API Web avec ASP.NET Core</a></p>

<p>À un moment vous allez devoir ajouter les objets métiers Sage comme dépendances à votre projet. Je ne me rappelle plus comment j&#39;ai fait dans le mille-feuilles de menus et d&#39;options sur Visual Studio, il faut ajouter une « référence COM » quelque part et vous trouvez les objets métiers Sage dans une immense liste… Là aussi, les moteurs de recherches sont vos meilleurs alliés. Je sais juste qu&#39;à force d&#39;essayer je me suis retrouvé avec cette section dans mon fichier de projet <code>Passage.csproj</code> :</p>

<pre><code class="language-xml">  &lt;ItemGroup&gt;
    &lt;COMReference Include=&#34;Objets100cLib&#34;&gt;
      &lt;WrapperTool&gt;tlbimp&lt;/WrapperTool&gt;
      &lt;VersionMinor&gt;2&lt;/VersionMinor&gt;
      &lt;VersionMajor&gt;9&lt;/VersionMajor&gt;
      &lt;Guid&gt;8b42efd1-11de-4af5-8f95-2901702d7a46&lt;/Guid&gt;
      &lt;Lcid&gt;0&lt;/Lcid&gt;
      &lt;Isolated&gt;false&lt;/Isolated&gt;
      &lt;EmbedInteropTypes&gt;true&lt;/EmbedInteropTypes&gt;
    &lt;/COMReference&gt;
  &lt;/ItemGroup&gt;
</code></pre>

<p>Vous êtes prêt lorsque vous avez une petite API qui tourne avec, disons, un ApiController de test que vous pouvez interroger, si possible le <a href="https://swagger.io/" rel="nofollow">Swagger</a> d&#39;activé pour tester vos endpoints et que vous pouvez importer les objets métiers Sage dans votre code :</p>

<pre><code class="language-cs">using Objets100cLib;
</code></pre>

<h2 id="lire-des-infos-contenues-dans-sage-via-sql" id="lire-des-infos-contenues-dans-sage-via-sql">Lire des infos contenues dans Sage via SQL</h2>

<p>J&#39;en ai pas parlé jusqu&#39;ici mais c&#39;est importer de savoir qu&#39;on peut lire l&#39;intégralité du contenu stocké dans Sage sans toucher à Sage ni aux objets métiers mais simplement en lisant la base de données SQL Server ! Les données sont réparties sur beaucoup de tables que le PDF structure des fichiers documente copieusement. Par exemple la table <code>F_DOCENTETE</code> contient tous les entêtes de document dont les factures, <code>F_DOCLIGNE</code> contient chaque ligne de facture, <code>F_ARTICLE</code> les articles, <code>F_COMPTET</code> les comptes tiers et leurs champs d&#39;informations libres, etc.</p>

<p>Dans la pratique, j&#39;ai trouvé que c&#39;était souvent plus simple de faire une bonne grosse requête SQL directement sur la base plutôt que de s&#39;embêter avec l&#39;API des objets métiers pour créer des collections et galérer à filtrer les résultats.</p>

<p>Exemple de requête pour trouver les numéros de compte tiers avec une adresse e-mail donnée :</p>

<pre><code class="language-sql">SELECT CT_Num
FROM F_COMPTET
WHERE CT_EMail = &#39;client@example.com&#39;
</code></pre>

<p>Ou encore vérifier qu&#39;une référence de facture existe :</p>

<pre><code class="language-sql">SELECT DO_Ref
FROM F_DOCLIGNE
WHERE DO_Ref = &#39;REF549832&#39;
</code></pre>

<h2 id="se-connecter-à-sage-avec-les-objets-métiers" id="se-connecter-à-sage-avec-les-objets-métiers">Se connecter à Sage avec les objets métiers</h2>

<p>Mais alors attends, pourquoi se prendre la tête avec des objets métiers si on peut taper directement dans la base de données ? Parce qu&#39;il y a beaucoup de triggers et de colonnes obscures qui sont compliquées à mettre à jour à la main et vous risquez de corrompre votre Sage si vous les modifiez vous-même. Autant pour la lecture il n&#39;y a pas de problème, autant je ne me risquerai pas à exécuter le moindre INSERT ou UPDATE sur les tables de Sage.</p>

<p>Avant de passer à la phase modification, on va donc regarder comment utiliser les objets métiers pour se connecter à Sage.</p>

<h3 id="ouvrir-et-fermer-une-connexion" id="ouvrir-et-fermer-une-connexion">Ouvrir et fermer une connexion</h3>

<p>Selon l&#39;offre de Sage qu&#39;on a, on peut avoir plusieurs module auxquels se connecter. Ici on a la comptabilité et la gestion commerciale, et ça fait deux modules auxquels on peut se connecter via deux objets différents dans l&#39;API des objets métiers. La base compta est gérée via l&#39;objet <code>BSCPTAApplication100c</code> et la base gestion commerciale (que je vais abréger en gescom) est gérée via l&#39;objet <code>BSCIALApplication100c</code>. On ouvre et referme la connexion à ces deux objets avec une même interface, mais les deux objets permettent ensuite d&#39;accéder à différentes parties de Sage. Par exemple on manipule les comptes tiers avec la base compta mais on manipule les documents de vente avec la base gescom.</p>

<p>Le code suivant permet d&#39;ouvrir une connexion à chacune des deux bases puis de les refermer :</p>

<pre><code class="language-cs">using Objets100cLib;

namespace Passage
{
    internal class Sage
    {
        public static readonly string Server = @&#34;MON-SERVEUR\SAGE100&#34;;
        public static readonly string Database = &#34;MA-BASE-DE-TEST&#34;;
        public static readonly string User = &#34;MON-USER&#34;;
        public static readonly string Password = &#34;MON-MDP&#34;;

        public static void DemoConnexion()
        {
            // Ouverture de la base Comptabilité.
            var cpta = new BSCPTAApplication100c();
            cpta.CompanyServer = Server;
            cpta.CompanyDatabaseName = Database;
            cpta.Loggable.UserName = User;
            cpta.Loggable.UserPwd = Password;
            cpta.Open();
            if (cpta.IsOpen)
            {
                Console.WriteLine(&#34;Connecté à la base compta.&#34;);
                // Ici on peut interagir avec la base compta, par exemple :
                //   cpta.FactoryClient.ReadNumero(...)
                // Et on la referme après utilisation.
                cpta.Close();
            }
            else
            {
                Console.WriteLine(&#34;Échec de l&#39;ouverture de la base compta.&#34;);
            }

            // Ouverture de la base Gestion Commerciale.
            var cial = new BSCIALApplication100c();
            cial.CompanyServer = Server;
            cial.CompanyDatabaseName = Database;
            cial.Loggable.UserName = User;
            cial.Loggable.UserPwd = Password;
            cial.Open();
            if (cial.IsOpen)
            {
                Console.WriteLine(&#34;Connecté à la base gescom.&#34;);
                // Ici on peut interagir avec la base commerciale, par exemple :
                //   cial.CreateProcess_Document(DocumentType.DocumentTypeVenteCommande)
                // Et on la referme après utilisation.
                cial.Close();
            }
            else
            {
                Console.WriteLine(&#34;Échec de l&#39;ouverture de la base gescom.&#34;);
            }
        }
    }
}
</code></pre>

<p>Dans certains cas vous serez amené à devoir utiliser les deux bases en simultané et à leur permettre d&#39;interagir entre elle, en mettant la base compta à l&#39;attribut <code>CptaApplication</code> de la base gescom, sous peine de vous prendre des erreurs comme quoi une des deux bases est inaccessible :</p>

<pre><code class="language-cs">cial.CptaApplication = cpta;
</code></pre>

<h3 id="récupérer-un-objet-et-ses-propriétés" id="récupérer-un-objet-et-ses-propriétés">Récupérer un objet et ses propriétés</h3>

<p>Pour vérifier que vous pouvez lire les infos depuis la base compta vous pouvez essayer de lire les infos d&#39;un client, par exemple le client n°1000 :</p>

<pre><code class="language-cs">if (cpta.FactoryClient.ExistNumero(1000))
    objClient = cpta.FactoryClient.ReadNumero(1000);
if (objClient == null)
    return;

Console.WriteLine($&#34;Intitulé du compte 1000 : {objClient.CT_Intitule}&#34;);
</code></pre>

<p>Pour vérifier que vous pouvez lire les infos depuis la base gescom vous pouvez essayer de lire les infos d&#39;un article, par exemple le prix d&#39;achat de l&#39;article qui porte la référence « BOOK1312 » :</p>

<pre><code class="language-cs">if (!cial.FactoryArticle.ExistReference(&#34;BOOK1312&#34;))
    return AdhesionResult.Result.ARTICLE_NOT_FOUND;
IBOArticle3 article = cial.FactoryArticle.ReadReference(&#34;BOOK1312&#34;);
double prixAchat = article.AR_PrixAchat;
</code></pre>

<p>Euh <code>CT_Intitule</code> ? <code>AR_PrixAchat</code> ? Et ça sort d&#39;où ces commandes <code>ExistNumero</code>, <code>ReadReference</code> ? Tout est dans le PDF objets métiers !</p>

<p>Dans la suite de l&#39;article je ne recopie pas toutes ces lignes, mais toute manipulation en lecture et en écriture avec les objets métiers doit se faire avec la ou les bonnes connexions ouvertes. C&#39;est relativement rapide donc à moins d&#39;un gros flux de requêtes ça n&#39;a pas l&#39;air de poser problème d&#39;ouvrir et fermer la connexion à chaque opération.</p>

<h3 id="récupérer-un-ensemble-d-objets" id="récupérer-un-ensemble-d-objets">Récupérer un ensemble d&#39;objets</h3>

<p>Je ne vais pas rentrer dans les détails ici mais la plupart des objets qui peuvent se lister ont une classe associée nommée Factory, e.g. <code>IBOArticleFactory3</code>, qui renvoient des <em>collections</em>, et ces objets peuvent être énumérés. Là encore il y a des explications succinctes mais suffisantes dans les PDF. Comme expliqué plus haut, je trouve que l&#39;interface est trop limitée par rapport à une requête SQL, mais peut-être que je n&#39;ai juste pas passé assez de temps à essayer d&#39;arriver à mes fins avec leur API.</p>

<h2 id="modifier-des-infos-contenues-dans-sage" id="modifier-des-infos-contenues-dans-sage">Modifier des infos contenues dans Sage</h2>

<p>On va donc voir ici comment utiliser les objets métiers pour ça. Si c&#39;est pas déjà fait, je vous conseille de parcourir le PDF objets métiers car je vais me concentrer sur des exemples d&#39;utilisation concrets et qu&#39;il y a des concepts expliqués à ne pas louper comme la <em>persistance des données</em>, les champs par défaut de certains objets lors de leur création, etc. Cela dit, le PDF n&#39;est pas toujours très précis et il vaut mieux faire ses tests ponctués de <code>Console.WriteLine</code> pour s&#39;assurer qu&#39;on a bien tout compris.</p>

<h3 id="exemple-simple-changer-l-intitulé-d-un-client" id="exemple-simple-changer-l-intitulé-d-un-client">Exemple simple : changer l&#39;intitulé d&#39;un client</h3>

<p>On chope l&#39;objet client qui porte le numéro 123 et on met son intitulé de compte (nom de société, nom prénom, etc) en majuscules. Oui c&#39;est nul mais c&#39;est pour la démo :</p>

<pre><code class="language-cs">// 1) On récupère l&#39;objet client.
if (cpta.FactoryClient.ExistNumero(123))
    client = cpta.FactoryClient.ReadNumero(123);
if (client == null)
    return;
// 2) On fait notre traitement, on change l&#39;attribut qui va bien.
string nom = client.CT_Intitule;
nom = nom.ToUpper();
client.CT_Intitule = nom;
// 3) On sauvegarde nos changements.
client.Write();
</code></pre>

<p>Ce qu&#39;il faut noter ici c&#39;est qu&#39;on peut lire et écrire les attributs de nos objets métiers comme on veut, mais que les modifications ne sont pas enregistrés en base de données tant qu&#39;on n&#39;a pas utilisé <code>Write()</code> (ou <code>WriteDefault()</code>). C&#39;est seulement après cet appel que les modifications sont écrites en base de données. La validation des données—la taille des strings, des valeurs autorisées ou non, etc—se fait à deux endroits, parfois à l&#39;assignation d&#39;une valeur dans un champ, et parfois au moment de l&#39;écriture, et c&#39;est pourquoi il vaut mieux englober toute ses manipulation dans des gros blocs de capture d&#39;exception parce que ça peut péter à de multiples endroits.</p>

<h3 id="exemple-un-peu-moins-simple-changer-tout-un-tas-d-infos-client" id="exemple-un-peu-moins-simple-changer-tout-un-tas-d-infos-client">Exemple un peu moins simple : changer tout un tas d&#39;infos client</h3>

<p>Pareil que l&#39;exemple précédent mais avec plus de modifications. On imagine un objet <code>adhesion</code> qui contiendrait les infos fournies par une API externe sur une nouvelle adhésion, et qu&#39;on voudrait utiliser pour mettre à jour les infos de nos comptes clients.</p>

<p>Notez ici l&#39;existence de l&#39;objet <code>client.LivraisonPrincipal</code>, de type <code>IBOClientLivraison3</code>, et qu&#39;on met à jour en simultané de notre objet client. Dans les deux cas, les infos d&#39;adresse sont dans un sous-objet astucieusement nommé Adresse.</p>

<pre><code class="language-cs">// On remplace tout un tas de champ par ceux de notre objet adhésion.
// Notez comment on tronque certaines chaînes, car elles peuvent avoir
// une limite de taille (pas toujours clairement précisée d&#39;ailleurs…)
client.CT_Intitule = adhesion.FullName;
client.CT_Classement = Utilities.Truncate(adhesion.FullName, 17);
client.CT_Contact = adhesion.FullName;
client.LivraisonPrincipal.LI_Contact = adhesion.FullName;
client.LivraisonPrincipal.LI_Intitule = adhesion.FullName;

address = Utilities.Truncate(adhesion.Address, 35).ToUpper();
client.Adresse.Adresse = address;
client.Adresse.Complement = &#34;&#34;;
client.LivraisonPrincipal.Adresse.Adresse = address;
client.LivraisonPrincipal.Adresse.Complement = &#34;&#34;;

zipCode = Utilities.Truncate(adhesion.ZipCode, 9).ToUpper();
client.Adresse.CodePostal = zipCode;
client.LivraisonPrincipal.Adresse.CodePostal = zipCode;

city = Utilities.Truncate(adhesion.City, 35).ToUpper();
client.Adresse.Ville = city;
client.LivraisonPrincipal.Adresse.Ville = city;

payerCountry = Utilities.Truncate(adhesion.PayerCountry, 35).ToUpper();
client.Adresse.Pays = payerCountry;
client.LivraisonPrincipal.Adresse.Pays = payerCountry;

phone = Utilities.Truncate(adhesion.phone, 21);
client.Telecom.Telephone = phone;
client.LivraisonPrincipal.Telecom.Telephone = phone;

// On met à jour un champ d&#39;information libre, identifié par son nom dans Sage.
// Attention à bien utiliser le bon type, SSMS peut être utile ici
// pour récupérer le type de la colonne correspondante.
DateTime dateTime = Utilities.ParseRfc3339(adhesion.Date) ?? DateTime.Now;
client.InfoLibre[&#34;Dernière année d&#39;adhésion&#34;] = dateTime.Year.ToString();

// On écrit l&#39;objet client mais aussi l&#39;objet LivraisonPrincipal.
// Pas sûr que ça soit super utile mais j&#39;ai pas bien compris
// à quel point les objets s&#39;écrivaient en cascade ou pas,
// et ça ne coute pas grand chose de toute façon.
client.Write();
client.LivraisonPrincipal.Write();
</code></pre>

<h3 id="exemple-avancé-créer-une-facture" id="exemple-avancé-créer-une-facture">Exemple avancé : créer une facture</h3>

<p>Dans ce dernier exemple, je vais créer une facture et l&#39;enregistrer. On utilise un objet un peu particulier, le résultat de <code>CreateProcess_Document</code>, qui émule les actions qu&#39;un utilisateur pourrait avoir en utilisant l&#39;interface graphique de Sage (son « processus », d&#39;où le nom de “process”).</p>

<pre><code class="language-cs">// On va créer une facture pour un article avec cette référence et cette gamme.
string refArticle = &#34;BOOK1312&#34;;
string refGamme = &#34;Collector&#34;;

// On crée le process. On va interagir à la fois avec cet objet,
// et aussi avec l&#39;objet IBODocumentVente3 qu&#39;il contient.
DocumentType docType = DocumentType.DocumentTypeVenteCommande;
IPMDocument process = cial.CreateProcess_Document(docType);
IBODocumentVente3 facture = (IBODocumentVente3)process.Document;
// On commence par écrire les attributs par défaut :
facture.SetDefault();
// On attribue un objet client récupéré plus tôt :
facture.SetDefaultClient(client);
// On attribue un numéro de pièce :
facture.SetDefaultDO_Piece();
// On modifie quelques attributs supplémentaires selon nos besoins :
facture.LieuLivraison = client.LivraisonPrincipal;
facture.DepotStockage = cial.FactoryDepot.ReadIntitule(adhesion.Depot);
facture.DO_NoWeb = &#34;CMD_123456&#34;;
facture.DO_Ref = &#34;XX123456&#34;;
facture.DO_Date = dateTime; // objet de type DateTime

// Est-ce l&#39;article demandé existe bien ?
if (!cial.FactoryArticle.ExistReference(refArticle))
    return &#34;ARTICLE_NOT_FOUND&#34;;
IBOArticle3 article = cial.FactoryArticle.ReadReference(refArticle);

// Est-ce que la gamme de l&#39;article demandée existe bien ?
if (!article.FactoryArticleGammeEnum1.ExistEnumere(refGammeType))
    return &#34;GAMME_NOT_FOUND&#34;;
IBOArticleGammeEnum3 gammeType = article.FactoryArticleGammeEnum1.ReadEnumere(refGammeType);

// On ajoute notre ligne de facture avec un article en utilisant sa gamme.
// Voir également dans les docs : AddArticle, AddArticleDoubleGamme.
process.AddArticleMonoGamme(gammeType, 1);

// Création de l&#39;acompte.
// Bon là je fais n&#39;importe quoi, c&#39;est pour l&#39;exemple.
if (adhesion.ItemAmount &gt; 0)
{
    IBODocumentAcompte3 acompte = (IBODocumentAcompte3)facture.FactoryDocumentAcompte.Create();
    acompte.SetDefault();
    acompte.DR_Date = dateTime;
    acompte.DR_Montant = ((double)amount) / 100; // attention aux types…
    // Je mets le bon réglement…
    if (!acompte.Reglement.FactoryReglement.ExistIntitule(&#34;ABC&#34;))
        return &#34;REGLEMENT_NOT_FOUND&#34;;
    acompte.Reglement = acompte.Reglement.FactoryReglement.ReadIntitule(&#34;ABC&#34;);
    // Je mets le bon code journal pour l&#39;acompte…
    if (!cpta.FactoryJournal.ExistNumero(&#34;DEF&#34;))
        return &#34;CODE_JOURNAL_NOT_FOUND&#34;;
    acompte.Reglement.JournalClient = cpta.FactoryJournal.ReadNumero(&#34;DEF&#34;);
    // Enfin, je n&#39;oublie pas d&#39;écrire mon objet d&#39;acompte.
    acompte.Write();
}

// L&#39;objet process a un attribut qui permet de vérifier
// s&#39;il n&#39;y a pas d&#39;erreur à la création.
if (!process.CanProcess)
{
    foreach (IFailInfo error in process.Errors)
    {
        Logger.LogError(
            &#34;Impossible de créer le document : {n} {text}&#34;,
            error.Indice,
            error.Text
        );
    }
    return &#34;CANT_CREATE_DOCUMENT&#34;;
}
Logger.LogInformation(&#34;Document prêt pour création.&#34;);

// Enfin, on enregistre les objets.
process.Process();
Logger.LogInformation(&#34;Document créé.&#34;);
client.Write();
client.LivraisonPrincipal.Write();
Logger.LogInformation(&#34;Compte client et adresse de livraison principale mis à jour.&#34;);
</code></pre>

<p>Si tout se passe bien, on se retrouve avec un bon de commande dans Sage que l&#39;on peut ensuite passer en facture comptabilisée à la main.</p>

<h2 id="conclusion" id="conclusion">Conclusion</h2>

<p>L&#39;autre API dont je n&#39;ai pas parlé, notre module d&#39;intranet, permet de récupérer les infos d&#39;adhésion depuis HelloAsso et de les traiter avec une file de messages, avec une interface graphique sympa, une base de données PostgreSQL, et tout un tas de choses que je maîtrise bien mieux qu&#39;une API en C# sur un serveur Windows derrière N firewalls et un VPN. C&#39;est vachement plus simple de gérer les notifications en provenance de HelloAsso depuis ce module que depuis Passage, qui peut donc ne contenir que du code en rapport avec la base SQL ou les objets métiers et des contrôleurs les plus légers possible.</p>

<p>J&#39;espère que cet article sera utile parce que j&#39;ai passé pas mal de temps à m&#39;y retrouver dans cet écosystème hostile. N&#39;hésitez pas à m&#39;écrire si vous avez besoin d&#39;un coup de main, je ne garantis pas de pouvoir répondre rapidement mais j&#39;essayerai et je pourrai compléter cet article en conséquence.</p>

<p><a href="/dece/tag:backfromthecodemines" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">backfromthecodemines</span></a></p>
]]></content:encoded>
      <guid>https://textes.pistache.land/dece/creer-une-api-web-pour-interagir-avec-sage-100</guid>
      <pubDate>Fri, 17 May 2024 12:48:24 +0200</pubDate>
    </item>
    <item>
      <title>Notes sur une formation en œnologie</title>
      <link>https://textes.pistache.land/dece/notes-sur-une-formation-en-oenologie</link>
      <description>&lt;![CDATA[J&#39;aime bien boire du vin, mais je n&#39;aimais pas devoir acheter du vin car je ne comprenais pas grand chose et ça m&#39;empêchait de choisir des bonnes bouteilles, me projetant perpétuellement dans les bras perfides du merlot Roche Mazet. Ma chère et tendre Emma m&#39;a judicieusement offert une journée de formation, la WSET1, qui donne les bases pour comprendre un peu mieux ce qui se passe dans son verre, et cet article vient tenter de résumer ce que j&#39;y ai appris. 🍷🤔 !--more--&#xA;&#xA;Je vous épargne gentiment les longues énumérations de noms de domaines, de cépages, avec des caractéristiques inertes, parce que ça n&#39;a pas d&#39;intérêt ici.&#xA;&#xA;Les régions et les cépages&#xA;&#xA;Les principales régions viticoles en France sont sur cette carte, qui est la moins illisible que j&#39;ai trouvé mais forcément incomplète et simpliste :&#xA;&#xA;Carte des régions viticoles&#xA;&#xA;On y fait des vins différents mais pour faire simple on peut dire que tout ce qui est au dessus de Lyon est un climat frais, et en dessous c&#39;est un climat chaud.&#xA;&#xA;Ensuite on a les différents cépages, qui est le terme œnologique pour désigner la variété botanique de la vigne, Vitis vinifera. Chaque région a des cépages spécifiquement adaptés à son climat, à son sol. Par exemple dans le Bordelais on utilise beaucoup de cabernet sauvignon, alors que dans le Chablis (dans l&#39;Yonne) on utilise surtout du chardonnay.&#xA;&#xA;Il y a des cépages blancs et des cépages rouges. Ces derniers ont une pellicule chargés en tanins, ce qui donne aux grains leur couleur foncée et au vin rouge son astringence.&#xA;&#xA;La vinification&#xA;&#xA;Le grain se charge en sucre et en eau sous l&#39;influence de la chaleur et du Soleil, et perd en même temps en acidité. Ce phénomène est plus important dans les climats chaud.&#xA;&#xA;On a ensuite plusieurs opérations à réaliser, pas toutes et pas dans le même ordre selon si on fait du vin blanc ou du vin rouge !&#xA;&#xA;Le foulage est le fait de broyer grossièrement des grains récoltés, ce qu&#39;on faisait autrefois aux pieds. 💃🍇&#xA;&#xA;La fermentation est l&#39;action des levures, souvent ajoutées, pour consommer les sucres et produire de l&#39;alcool et du dioxyde de carbone (c&#39;est quoi le bilan carbone du vin tiens ?). Ça peut durer de quelques jours à quelques mois. 🫧&#xA;&#xA;Le soutirage est l&#39;extraction du vin depuis le moût. On a alors le vin de goutte, liquide, et le vin de presse, solide. 🌊&#xA;&#xA;Le pressurage consiste à presser le moût (pour le vin blanc) ou les pellicules (pour le vin rouge). ⚙️&#xA;&#xA;L&#39;élevage est la mise au repos du vin pendant quelques mois à quelques années, dans des cuves en inox ou dans des fûts de chêne, ou si on veut tricher un peu dans des cuves en inox où l&#39;on a mis des morceaux de chêne, parce que l&#39;intérêt est quand même de donner un goût boisé au vin. ⏱️&#xA;&#xA;Enfin, il y a la mise en bouteille. 🍾&#xA;&#xA;Vins blancs&#xA;&#xA;Foulage&#xA;Pressurage des grains pour récupérer tout le jus.&#xA;Fermentation&#xA;Élevage&#xA;Mise en bouteille&#xA;&#xA;Vins rouges&#xA;&#xA;Foulage&#xA;Fermentation du vin avec toute la matière solide (pellicules, pépins)&#xA;Soutirage&#xA;Pressurage du vin de presse pour extraire tout le vin restant&#xA;Élevage&#xA;Mise en bouteille&#xA;&#xA;Vins rosés&#xA;&#xA;Le vin rosé est fait comme le vin rouge, sauf que lors de la fermentation on ne laisse que très peu de temps, quelques heures seulement, le jus avec la matière solide, ce qui l&#39;empêche de prendre trop de tanins et de trop se colorer. On soutire donc très tôt, et la fermentation continue avec le liquide uniquement ensuite.&#xA;&#xA;On voit alors qu&#39;on peut faire du vin blanc à partir de cépages rouges : il suffit de ne pas laisser la matière solide pendant la fermentation. L&#39;inverse, faire du vin rouge avec des cépages blancs, est impossible.&#xA;&#xA;Caractéristiques de vins&#xA;&#xA;Types&#xA;&#xA;On parle de vins tranquilles pour la plupart d&#39;entre eux. On laisse la fermentation se terminer d&#39;elle-même, et le dioxyde de carbone s&#39;échapper. Ils portent les noms de leur région de production ou de leur cépage.&#xA;&#xA;Les vins effervescents sont mousseux/pétillants comme le champagne ou le prosecco. On essaye soit de conserver le dioxyde de carbone produit par les levures, ou alors on triche et on le rajoute après.&#xA;&#xA;Les vins fortifiés sont ceux où il y a eu ajout d&#39;alcool, comme le porto. Cela permet de stopper la fermentation en tuant les levures et de conserver du sucre dans le vin, ce qui donne d&#39;excellents vins apéritifs.&#xA;&#xA;Douceur&#xA;&#xA;On a un spectre entre d&#39;un côté les vins dits sec, et de l&#39;autre ceux dits doux ou rond. Les vins secs sont peu sucrés car les sucres ont été entièrement consommé par les levures. Les vins de douceur moyenne ont encore un peu de sucre car les levures n&#39;ont pas tout consommé, ou bien du jus de raison non fermenté a été ajouté. Les vins doux ont typiquement beaucoup de sucre initialement, ou bien c&#39;est du vin fortifié.&#xA;&#xA;Acidité&#xA;&#xA;L&#39;acidité d&#39;un vin fait saliver. Elle permet également de tirer en longueur, dans le temps, l&#39;effet des saveurs en bouche. Vins acides : chablis, riesling, sauvignon blanc, etc. L&#39;acidité ne sent rien, elle se goûte.&#xA;&#xA;Tanins&#xA;&#xA;Les tannins sont des particules astringentes, qui provoquent comme une sécheresse en bouche, donc c&#39;est plus une sensation qu&#39;une saveur. Vins tanniques : les bordeaux, le chianti, etc. Les tanins ne se sentent pas.&#xA;&#xA;Alcool&#xA;&#xA;On a normalement entre 11.5° et 15° d&#39;alcool dans un vin. L&#39;alcool remplit surtout un rôle social. L&#39;alcool se sent.&#xA;&#xA;Corps&#xA;&#xA;On dit d&#39;un vin qu&#39;il a du corps selon… euh… qu&#39;il prend de la place dans la bouche ? Contrairement à un vin plus délicat, plus subtil ? Ça me semble pas très clair ni très utile comme critère.&#xA;&#xA;Balance acidité, tanins, alcool et sucre&#xA;&#xA;Une façon de voir l&#39;équilibre des goûts dans le vin est de voir d&#39;un côté l&#39;alcool et le sucre, et de l&#39;autre l&#39;acidité et les tanins. Un bon vin parviendra à trouver son propre équilibre !&#xA;&#xA;Odeurs et saveurs&#xA;&#xA;À chaque cépage, territoire, vin, son ensemble de saveur ! L&#39;exercice de décrire les saveurs d&#39;un vin paraît parfois trop sophistiqué mais si on se laisse prendre au jeu d&#39;écouter au maximum ses sens et d&#39;attraper les mots dès qu&#39;ils nous passent en tête, on se retrouve vite à dire des choses plus complexes qu&#39;on ne l&#39;aurait imaginer : mûre, brioche, pomme verte, bouquets de fleurs, tarte tatin, saumon fumé, etc.&#xA;&#xA;Il y a des saveurs qui reviennent souvent comme le citron, la cerise, la vanille, le bois fumé, mais plutôt que de retenir quel vin goûte typiquement quelle saveur, je trouve ça plus intéressant d&#39;essayer à chaque fois de trouver ce à quoi ça nous fait penser.&#xA;&#xA;Quand on découvre un vin, on commence par le sentir. On peut le sentir directement après l&#39;avoir versé, puis le faire tourner dans son verre et sentir de nouveau, des fois l&#39;odeur est légèrement différente, plus forte, plus riche.&#xA;&#xA;Accords mets et vins&#xA;&#xA;Bon j&#39;ai pas retenu grand chose, mais c&#39;est intéressant de voir que nos papilles sont facilement occupées par un aspect du plat qu&#39;on mange au point d&#39;annuler ces mêmes aspects dans le vin qu&#39;on boit. Par exemple, manger une entrée forte en acidité (pamplemousse, pomme) atténue fortement l&#39;acidité d&#39;un vin blanc sec comme un chablis, ce qui lui permet de laisser parler ses touches fruitées. Autre exemple, un plat bien mijoté comme du bœuf bourguignon et salé juste ce qu&#39;il faut va réduire les tanins d&#39;un vin rouge qui paraîtrait pourtant fort astringent s&#39;il était bu seul.&#xA;&#xA;Ceci dit, un bon plat et une bonne bouteille, ça s&#39;accorde en général bien sans trop faire attention pour la majorité des gens. Mais bon un gâteau au chocolat avec un porto là, pfouah…&#xA;&#xA;stock photo de vin&#xA;&#xA;Ce sur quoi je passe&#xA;&#xA;Comment ouvrir une bouteille, la liste des cépages et régions internationales de la WSET1, les odeurs et saveurs typiques de tels cépages et telles régions.&#xA;&#xA;- -&#xA;&#xA;  Wouaaah merci dece pour ces notes trop courtes pour être utiles à quiconque 🤩&#xA;&#xA;OK alors on se calme tout de suite ! J&#39;aimerais tenter une alternative à ma technique de prise de notes actuelle qui suit à peu près la méthode PARA en couplant quelque chose qui s&#39;approche du Memex de Cory Doctorow pour certains contenus, l&#39;idée principale étant que la mise à disposition au public implique une rigueur dans la prise de note, la compréhension du sujet et un partage d&#39;information. Mon wiki contient moult fiches qui auraient gagnées à être des contenus publiés, marqués dans le temps ou progressivement mis à jour. Cet article est donc un premier test dans cette direction, plutôt que de croupir hors-ligne ! Projet Xanadu me voici !!&#xA;&#xA;Côté vin je vais voir si c&#39;est intéressant de tenir une liste des bouteilles que j&#39;ai pu boire avec mes impressions. « Hmm… ce Côtes du Rhône Franprix a un nez surprenant… » ou encore « Aaah, je sens que je suis bourré ».]]&gt;</description>
      <content:encoded><![CDATA[<p>J&#39;aime bien boire du vin, mais je n&#39;aimais pas devoir acheter du vin car je ne comprenais pas grand chose et ça m&#39;empêchait de choisir des bonnes bouteilles, me projetant perpétuellement dans les bras perfides du merlot Roche Mazet. Ma chère et tendre Emma m&#39;a judicieusement offert une journée de formation, la WSET1, qui donne les bases pour comprendre un peu mieux ce qui se passe dans son verre, et cet article vient tenter de résumer ce que j&#39;y ai appris. 🍷🤔 </p>

<p>Je vous épargne gentiment les longues énumérations de noms de domaines, de cépages, avec des caractéristiques inertes, parce que ça n&#39;a pas d&#39;intérêt ici.</p>

<h2 id="les-régions-et-les-cépages" id="les-régions-et-les-cépages">Les régions et les cépages</h2>

<p>Les principales <strong>régions viticoles</strong> en France sont sur cette carte, qui est la moins illisible que j&#39;ai trouvé mais forcément incomplète et simpliste :</p>

<p><img src="https://files.dece.space/blog/textes/carte-regions-vin-de-france-scaled-1.jpg" alt="Carte des régions viticoles"></p>

<p>On y fait des vins différents mais pour faire simple on peut dire que tout ce qui est au dessus de Lyon est un climat frais, et en dessous c&#39;est un climat chaud.</p>

<p>Ensuite on a les différents <strong>cépages</strong>, qui est le terme œnologique pour désigner la variété botanique de la vigne, <em>Vitis vinifera</em>. Chaque région a des cépages spécifiquement adaptés à son climat, à son sol. Par exemple dans le Bordelais on utilise beaucoup de cabernet sauvignon, alors que dans le Chablis (dans l&#39;Yonne) on utilise surtout du chardonnay.</p>

<p>Il y a des cépages blancs et des cépages rouges. Ces derniers ont une pellicule chargés en tanins, ce qui donne aux grains leur couleur foncée et au vin rouge son astringence.</p>

<h2 id="la-vinification" id="la-vinification">La vinification</h2>

<p>Le grain se charge en sucre et en eau sous l&#39;influence de la chaleur et du Soleil, et perd en même temps en acidité. Ce phénomène est plus important dans les climats chaud.</p>

<p>On a ensuite plusieurs opérations à réaliser, pas toutes et pas dans le même ordre selon si on fait du vin blanc ou du vin rouge !</p>

<p>Le <strong>foulage</strong> est le fait de broyer grossièrement des grains récoltés, ce qu&#39;on faisait autrefois aux pieds. 💃🍇</p>

<p>La <strong>fermentation</strong> est l&#39;action des levures, souvent ajoutées, pour consommer les sucres et produire de l&#39;alcool et du dioxyde de carbone (c&#39;est quoi le bilan carbone du vin tiens ?). Ça peut durer de quelques jours à quelques mois. 🫧</p>

<p>Le <strong>soutirage</strong> est l&#39;extraction du vin depuis le moût. On a alors le vin de goutte, liquide, et le vin de presse, solide. 🌊</p>

<p>Le <strong>pressurage</strong> consiste à presser le moût (pour le vin blanc) ou les pellicules (pour le vin rouge). ⚙️</p>

<p>L&#39;<strong>élevage</strong> est la mise au repos du vin pendant quelques mois à quelques années, dans des cuves en inox ou dans des fûts de chêne, ou si on veut tricher un peu dans des cuves en inox où l&#39;on a mis des morceaux de chêne, parce que l&#39;intérêt est quand même de donner un goût boisé au vin. ⏱️</p>

<p>Enfin, il y a la <strong>mise en bouteille</strong>. 🍾</p>

<h3 id="vins-blancs" id="vins-blancs">Vins blancs</h3>
<ol><li>Foulage</li>
<li>Pressurage des grains pour récupérer tout le jus.</li>
<li>Fermentation</li>
<li>Élevage</li>
<li>Mise en bouteille</li></ol>

<h3 id="vins-rouges" id="vins-rouges">Vins rouges</h3>
<ol><li>Foulage</li>
<li>Fermentation du vin avec toute la matière solide (pellicules, pépins)</li>
<li>Soutirage</li>
<li>Pressurage du vin de presse pour extraire tout le vin restant</li>
<li>Élevage</li>
<li>Mise en bouteille</li></ol>

<h3 id="vins-rosés" id="vins-rosés">Vins rosés</h3>

<p>Le vin rosé est fait comme le vin rouge, sauf que lors de la fermentation on ne laisse que très peu de temps, quelques heures seulement, le jus avec la matière solide, ce qui l&#39;empêche de prendre trop de tanins et de trop se colorer. On soutire donc très tôt, et la fermentation continue avec le liquide uniquement ensuite.</p>

<p>On voit alors qu&#39;on peut faire du vin blanc à partir de cépages rouges : il suffit de ne pas laisser la matière solide pendant la fermentation. L&#39;inverse, faire du vin rouge avec des cépages blancs, est impossible.</p>

<p><img src="https://www.shutterstock.com/shutterstock/photos/426393937/display_1500/stock-photo-gathered-the-grapes-and-make-wine-426393937.jpg" alt="" title="Sproutch sproutch c&#39;est le foulage."></p>

<h2 id="caractéristiques-de-vins" id="caractéristiques-de-vins">Caractéristiques de vins</h2>

<h3 id="types" id="types">Types</h3>

<p>On parle de vins <em>tranquilles</em> pour la plupart d&#39;entre eux. On laisse la fermentation se terminer d&#39;elle-même, et le dioxyde de carbone s&#39;échapper. Ils portent les noms de leur région de production ou de leur cépage.</p>

<p>Les vins <em>effervescents</em> sont mousseux/pétillants comme le champagne ou le prosecco. On essaye soit de conserver le dioxyde de carbone produit par les levures, ou alors on triche et on le rajoute après.</p>

<p>Les vins <em>fortifiés</em> sont ceux où il y a eu ajout d&#39;alcool, comme le porto. Cela permet de stopper la fermentation en tuant les levures et de conserver du sucre dans le vin, ce qui donne d&#39;excellents vins apéritifs.</p>

<h3 id="douceur" id="douceur">Douceur</h3>

<p>On a un spectre entre d&#39;un côté les vins dits sec, et de l&#39;autre ceux dits doux ou rond. Les vins secs sont peu sucrés car les sucres ont été entièrement consommé par les levures. Les vins de douceur moyenne ont encore un peu de sucre car les levures n&#39;ont pas tout consommé, ou bien du jus de raison non fermenté a été ajouté. Les vins doux ont typiquement beaucoup de sucre initialement, ou bien c&#39;est du vin fortifié.</p>

<h3 id="acidité" id="acidité">Acidité</h3>

<p>L&#39;acidité d&#39;un vin fait saliver. Elle permet également de tirer en longueur, dans le temps, l&#39;effet des saveurs en bouche. Vins acides : chablis, riesling, sauvignon blanc, etc. L&#39;acidité ne sent rien, elle se goûte.</p>

<h3 id="tanins" id="tanins">Tanins</h3>

<p>Les tannins sont des particules astringentes, qui provoquent comme une sécheresse en bouche, donc c&#39;est plus une sensation qu&#39;une saveur. Vins tanniques : les bordeaux, le chianti, etc. Les tanins ne se sentent pas.</p>

<h3 id="alcool" id="alcool">Alcool</h3>

<p>On a normalement entre 11.5° et 15° d&#39;alcool dans un vin. L&#39;alcool remplit surtout un rôle social. L&#39;alcool se sent.</p>

<h3 id="corps" id="corps">Corps</h3>

<p>On dit d&#39;un vin qu&#39;il a du corps selon… euh… qu&#39;il prend de la place dans la bouche ? Contrairement à un vin plus délicat, plus subtil ? Ça me semble pas très clair ni très utile comme critère.</p>

<h3 id="balance-acidité-tanins-alcool-et-sucre" id="balance-acidité-tanins-alcool-et-sucre">Balance acidité, tanins, alcool et sucre</h3>

<p>Une façon de voir l&#39;équilibre des goûts dans le vin est de voir d&#39;un côté l&#39;alcool et le sucre, et de l&#39;autre l&#39;acidité et les tanins. Un bon vin parviendra à trouver son propre équilibre !</p>

<p><img src="https://www.shutterstock.com/shutterstock/photos/53331535/display_1500/stock-photo-man-smelling-a-glass-of-red-wine-53331535.jpg" alt="" title="Hmm alors ça sent le vin rouge et euh..."></p>

<h2 id="odeurs-et-saveurs" id="odeurs-et-saveurs">Odeurs et saveurs</h2>

<p>À chaque cépage, territoire, vin, son ensemble de saveur ! L&#39;exercice de décrire les saveurs d&#39;un vin paraît parfois trop sophistiqué mais si on se laisse prendre au jeu d&#39;écouter au maximum ses sens et d&#39;attraper les mots dès qu&#39;ils nous passent en tête, on se retrouve vite à dire des choses plus complexes qu&#39;on ne l&#39;aurait imaginer : mûre, brioche, pomme verte, bouquets de fleurs, tarte tatin, saumon fumé, etc.</p>

<p>Il y a des saveurs qui reviennent souvent comme le citron, la cerise, la vanille, le bois fumé, mais plutôt que de retenir quel vin goûte typiquement quelle saveur, je trouve ça plus intéressant d&#39;essayer à chaque fois de trouver ce à quoi ça nous fait penser.</p>

<p>Quand on découvre un vin, on commence par le sentir. On peut le sentir directement après l&#39;avoir versé, puis le faire tourner dans son verre et sentir de nouveau, des fois l&#39;odeur est légèrement différente, plus forte, plus riche.</p>

<h2 id="accords-mets-et-vins" id="accords-mets-et-vins">Accords mets et vins</h2>

<p>Bon j&#39;ai pas retenu grand chose, mais c&#39;est intéressant de voir que nos papilles sont facilement occupées par un aspect du plat qu&#39;on mange au point d&#39;annuler ces mêmes aspects dans le vin qu&#39;on boit. Par exemple, manger une entrée forte en acidité (pamplemousse, pomme) atténue fortement l&#39;acidité d&#39;un vin blanc sec comme un chablis, ce qui lui permet de laisser parler ses touches fruitées. Autre exemple, un plat bien mijoté comme du bœuf bourguignon et salé juste ce qu&#39;il faut va réduire les tanins d&#39;un vin rouge qui paraîtrait pourtant fort astringent s&#39;il était bu seul.</p>

<p>Ceci dit, un bon plat et une bonne bouteille, ça s&#39;accorde en général bien sans trop faire attention pour la majorité des gens. Mais bon un gâteau au chocolat avec un porto là, pfouah…</p>

<p><img src="https://www.shutterstock.com/shutterstock/photos/517306303/display_1500/stock-photo-delicious-dinner-with-grilled-vegetables-and-wine-517306303.jpg" alt="stock photo de vin" title="Moi qui sert un cabernet sauvignon et des aubergines grillées à mes convives"></p>

<h2 id="ce-sur-quoi-je-passe" id="ce-sur-quoi-je-passe">Ce sur quoi je passe</h2>

<p>Comment ouvrir une bouteille, la liste des cépages et régions internationales de la WSET1, les odeurs et saveurs typiques de tels cépages et telles régions.</p>

<hr>

<blockquote><p>Wouaaah merci dece pour ces notes trop courtes pour être utiles à quiconque 🤩</p></blockquote>

<p>OK alors on se calme tout de suite ! J&#39;aimerais tenter une alternative à ma technique de prise de notes actuelle qui suit à peu près la <a href="https://fortelabs.com/blog/para/" rel="nofollow">méthode PARA</a> en couplant quelque chose qui s&#39;approche du <a href="https://pluralistic.net/2021/05/09/the-memex-method/" rel="nofollow">Memex de Cory Doctorow</a> pour certains contenus, l&#39;idée principale étant que la mise à disposition au public implique une rigueur dans la prise de note, la compréhension du sujet et un partage d&#39;information. Mon wiki contient moult fiches qui auraient gagnées à être des contenus publiés, marqués dans le temps ou progressivement mis à jour. Cet article est donc un premier test dans cette direction, plutôt que de croupir hors-ligne ! Projet Xanadu me voici !!</p>

<p>Côté vin je vais voir si c&#39;est intéressant de tenir une liste des bouteilles que j&#39;ai pu boire avec mes impressions. « Hmm… ce Côtes du Rhône Franprix a un nez surprenant… » ou encore « Aaah, je sens que je suis bourré ».</p>
]]></content:encoded>
      <guid>https://textes.pistache.land/dece/notes-sur-une-formation-en-oenologie</guid>
      <pubDate>Wed, 13 Mar 2024 22:33:01 +0100</pubDate>
    </item>
    <item>
      <title>Améliorer des données d&#39;autochtonie d&#39;odonates à coups de regex</title>
      <link>https://textes.pistache.land/dece/ameliorer-des-donnees-dautochtonie-dodonates-a-coups-de-regex</link>
      <description>&lt;![CDATA[Sur l&#39;atlas des odonates (libellules et demoiselles), on a une problématique d&#39;incertitude concernant l&#39;autochtonie des espèces sur les mailles où elles ont été observées. Vous n&#39;avez pas forcément besoin de comprendre cette phrase pour lire cet article, tant que vous aimez bien les problématiques de gestion de données et les regex. !--more--&#xA;&#xA;L&#39;autochtonie ? Les exuvies ?&#xA;&#xA;OK, petit lexique.&#xA;&#xA;Atlas : un ensemble de cartes représentant la présence ou non d&#39;espèces sur un territoire donnée, généralement par maille.&#xA;&#xA;Maille : une zone, un carré sur la carte. Par exemple en France on utilise souvent des mailles de 10km² tracées avec une projection Lambert93, ce qui donne des mailles identifiables avec un code tel que 10kmL93E024N677.&#xA;&#xA;Autochtonie : une espèce est autochtone sur un lieu si on peut y observer la reproduction, la ponte, la naissance, etc ; en gros, qu&#39;on ne l&#39;a pas observée juste de passage, comme ça peut arriver avec les odonates qui peuvent se balader loin de leur lieu de naissance et de reproduction.&#xA;&#xA;Exuvie : la mue laissée par la larve d&#39;odonate avant qu&#39;elle « émerge » en tant qu&#39;individu adulte. Quelques photos dans cette clé d&#39;identification. Si on trouve une exuvie quelque part, c&#39;est donc qu&#39;il y a bien eu émergence d&#39;adulte, et donc que l&#39;espèce observée est autochtone à cet endroit (Ruffoni, 2018).&#xA;&#xA;Les données&#xA;&#xA;On utilise une extraction OpenObs pour alimenter notre atlas, et ces tables contiennent un champ &#34;Stade de vie&#34; mais celui-ci n&#39;est pas toujours renseigné correctement à cause de l&#39;hétérogénéité des jeux de données et des plateformes de saisie utilisées. Si on regarde bien cependant, l&#39;information peut parfois être retrouvée dans le champ &#34;Commentaires&#34; de l&#39;observation, où l&#39;observateur, parfois le producteur de la donnée, nous gratifie d&#39;informations plus ou moins cryptiques, à propos de l&#39;observation, ou de la météo, ou de son humeur… Dans cet article on va donc se pencher sur ce champ de commentaires et voir comment on peut l&#39;utiliser au mieux pour améliorer les infos d&#39;autochtonie.&#xA;&#xA;Beaucoup des idées ci-dessous proviennent des conseils d&#39;Alexia, notre géomaticienne avec qui j&#39;ai la joie quotidiennement renouvelée de travailler 😌&#xA;&#xA;Les regex ci-dessous sont au format PCRE2 (PHP 7.3 et plus). J&#39;ai remplacé les noms qui apparaissaient dans les commentaires par […].&#xA;&#xA;Pourquoi on ne peut pas juste grep exuvie&#xA;&#xA;On ne peut pas se baser simplement sur la présence du mot « exuvie » en commentaire d&#39;une observation pour pas mal de raisons.&#xA;&#xA;Déjà parce que parfois, c&#39;est écrit « pas d&#39;exuvies ». OK donc on n&#39;a qu&#39;à faire une regex qui enlève « pas [espace] d&#39;exuvies » ; pourquoi pas mais du coup, attention à ne pas ignorer les gros malins qui ont alors commenté « pas mal d&#39;exuvies » ! Il y a aussi quelques commentaires dans d&#39;autres langues, notamment en allemand : « viele exuvien » (plein), « altere Exuvien » (anciennes), « frische Exuvien » (fraîche), « keine Exuvien » (aucune). Exemples relous :&#xA;&#xA;Toutes émergented, pas mal d&#39;exuvies dans les iris&#xA;4 - males uniquement pas trouve d&#39;exuvie Ã  ce jour&#xA;pas encore trouvé d&#39;exuvies&#xA;M et F adultes et 1 M immatures tres tres frais (quasi emergent mais pas vu l&#39;exuvie!). Observations en compagnie de […].&#xA;&#xA;Parfois le commentaire est utilisé pour décrire d&#39;autres éléments de l&#39;observation, qui mentionnent le terme d&#39;exuvie mais sans être en rapport avec la quantité d&#39;exuvies trouvées dans l&#39;observation. Quelques exemples :&#xA;&#xA;Formation odonate et identification des exuvies organisée par l&#39;ALEPE avec […] et […]&#xA;rem. orig. : B, prospection exuvies, tronçon 2- src : Gard Nature - prot : Observation occasionnelle&#xA;territorialié- idsource : 10923- BDDexuvies2015modifexport.xlsx- 20161017&#xA;&#xA;À moins de faire une regex particulièrement illisible et constamment incomplète, c&#39;est impossible d&#39;utiliser un modèle de denylist) pour vérifier les exuvies, et donc détecter uniquement la présence du mot exuvie n&#39;est pas satisfaisant pour notre besoin ici. On va donc écrire une regex dont on utilisera les matchs pour affirmer la présence d&#39;une exuvie, quitte à avoir des faux négatifs, mais avec presque aucun faux positifs.&#xA;&#xA;Détails, astuces et mauvaises idées&#xA;&#xA;Si on souhaite se restreindre au modèle « [nombre] exuvie », il faut faire attention à ignorer tous les commentaires qui disent gentiment qu&#39;il y a « 0 exuvies » (mais pas ignorer « 10 exuvies » !). Bien entendu c&#39;est parfois écrit en toutes lettres : « Une exuvie », « Trois exuvies », « Quatre exuvies ».&#xA;&#xA;On aimerait bien ignorer les commentaires qui disent « aucune exuvie » ou « pas d&#39;exuvie », mais évidemment des petits malins ont commenté « Pas mal d&#39;exuvies » 😭&#xA;&#xA;On serait tenté de capturer plus de résultat en réduisant la recherche à « exu » car beaucoup de commentaires utilisent « ex » ou « exu » car « exuvie » c&#39;est trop long à écrire j&#39;imagine, mais c&#39;est sans compter la présence de mots comme « exutoire ». On a aussi envie de match les chaînes « exuvies trouvées » ou « exuvies récoltées », mais elles semblent pouvoir apparaître autant dans des affirmations positives que négatives !&#xA;&#xA;Parmi d&#39;autres détails, l&#39;orthographe officielle est « exuvie » mais elle est parfois orthographiée « éxuvie ». Enfin, la gestion de la casse est un problème de tous les instants, et il peut être intéressant de commencer par passer l&#39;entièreté de son jeu de données en minuscules pour simplifier l&#39;écriture des regex ensuite, ou d&#39;ajouter le flag i à ses patterns pour ignorer la casse.&#xA;&#xA;Protocole&#xA;&#xA;Préparation des données &#xA;&#xA;Depuis une extraction d&#39;OpenObs des insectes, préalablement filtrée sur l&#39;ordre Odonata, on extrait les observations dont les commentaires (colonne 80) contiennent le mot « exuvie » avec l&#39;excellent csvgrep :&#xA;&#xA;csvgrep&#xA;    -c 80 \&#xA;    -r &#34;[eEéÉèÈ]xuvie&#34; \&#xA;    extractINPNinsectes21092023Odonata.csv \&#xA;  /tmp/exuvia.csv&#xA;&#xA;On récupère la liste de ces commentaires dédupliqués et triés pour pouvoir tester nos regex facilement :&#xA;&#xA;… | csvcut -c 80 | sort -u   commentaireexuvieuniq.txt&#xA;&#xA;Ce fichier fait 4306 lignes.&#xA;&#xA;Compter les commentaires les plus simples&#xA;&#xA;Si le commentaire commence par « exuvie », sans compter quelques caractères parasites, alors nous n&#39;avons pas trouvé de contre-exemples au fait que l&#39;observation concerne bel et bien une ou plusieurs exuvies. &#xA;&#xA;Regex : /^[\-\\+]? [eé]xuvie/i&#xA;&#xA;Rien qu&#39;avec cette regex on a 348 matchs.&#xA;&#xA;Repérer les comptages d&#39;exuvies&#xA;&#xA;À défaut de pouvoir proprement ignorer les commentaires stipulant qu&#39;il n&#39;y a pas d&#39;exuvies parce qu&#39;on ne sait jamais quand un odonatologue décidera d&#39;annoter dans son patois qu&#39;il n&#39;a vu aucune exuvie, on peut essayer de cibler au mieux la présence d&#39;un certain nombre d&#39;exuvie, que ça soit en chiffres ou en toutes lettres.&#xA;&#xA;Pour les chiffres, sont valides les nombres à un chiffre de 1 à 9, ou n&#39;importe quel chiffre à partir de 2 chiffres par nombre. Théoriquement ça fait que « 00 exuvie » match, mais bon… Attention en revanche à la pattern /une exuvie/ car elle match la chaîne « aucune exuvie » 🫠 un petit negative lookbehind est donc de rigueur.&#xA;&#xA;On améliore ses résultats en ignorant certaines qualificatifs comme « ancienne » ou les genres. On détecte les m et f, voire mf qui servent à genrer les nombres, et les x neutres. Comme on est sympa, on match aussi les nombres en toutes lettres (enfin de un à neuf). On trouve également parfois des quantificateurs flous mais utiles, comme « nombreuses exuvies » ou « plusieurs exuvies ».&#xA;&#xA;Regex : /((0-9]{2,}|[1-9])(x|m|f|mf)?|(?&lt;!auc)une|qq|qlq|quelques|deux|trois|quatre|cinq|six|sept|huit|neuf|nombreuses|plusieurs)([[:blank:]les?|femelles?|anciennes?|vieilles?))?[[:blank:]]?[eé]xuvie/i&#xA;&#xA;Dans le détail :&#xA;&#xA;/(&#xA;    ([0-9]{2,}|[1-9])&#xA;    (x|m|f|mf)?&#xA;|&#xA;    (?&lt;!auc)une&#xA;|&#xA;    qq|qlq|quelques|deux|trois|quatre|cinq|six|sept|huit|neuf|nombreuses|plusieurs&#xA;)&#xA;([:blank:]les?|femelles?|anciennes?|vieilles?))?&#xA;[[:blank:]]?[eé]xuvie&#xA;/xi&#xA;&#xA;Tout de suite on passe à 2767 matchs !&#xA;&#xA;En général il semble plus prudent de ne pas supprimer les virgules car on n&#39;est jamais à l&#39;abri d&#39;un naturaliste fou qui aurait écrit « larves 4, exuvies 0 », qu&#39;un filtre trop enthousiaste interprèterait comme « larves 4 exuvies 0 » et bondirait sur « 4 exuvies ». En revanche, s&#39;il n&#39;y a rien après la mention d&#39;exuvie, on peut se permettre de compter dans un match une virgule entre un comptage et le mot exuvie, ce qui permet de match une bonne dizaine de cas supplémentaires.&#xA;&#xA;Regex :&#xA;&#xA;/(([0-9]{2,}|[1-9])(x|m|f|mf)?){1,2},?[[:blank:]]?[eé]xuvies?$/i&#xA;                               ^^^^^&#xA;                               un ou deux groupes (e.g. 1m, 2f, 3m4f, …)&#xA;&#xA;Quelques cas autres intéressants&#xA;&#xA;D&#39;autres quantificateurs imprécis mais on notera le « d&#39; » avant le mot exuvie.&#xA;&#xA;Regex : /(dizaines?|centaines?)[[:blank:]]d&#39;[eé]xuvie/i&#xA;&#xA;Enfin le mot « présence » est souvent utilisé aussi.&#xA;&#xA;Regex : /preé]sence[[:blank:][eé]xuvie/i&#xA;&#xA;Ce qui nous fait passer à 2828 matchs.&#xA;&#xA;Regex finale&#xA;&#xA;/(&#xA;  ^\-\\+]?[[:blank:]xuvie&#xA;|&#xA;  ((0-9]{2,}|[1-9])(x|m|f|mf)?|(?&lt;!auc)une|qq|qlq|quelques|deux|trois|quatre|cinq|six|sept|huit|neuf|nombreuses|plusieurs)([[:blank:]les?|femelles?|anciennes?|vieilles?))?[[:blank:]]?[eé]xuvie&#xA;|&#xA;  (([0-9]{2,}|[1-9])(x|m|f|mf)?){1,2},?[[:blank:]]?[eé]xuvies?$&#xA;|&#xA;  (dizaines?|centaines?)[[:blank:]]d&#39;[eé]xuvie&#xA;|&#xA;  preé]sence[[:blank:][eé]xuvie&#xA;)/xi&#xA;&#xA;Au final c&#39;est surtout la deuxième partie, où on cherche « [nombre] exuvie » qui rapporte un maximum d&#39;information, en tout cas sur la diversité des commentaires disponibles car il ne faut pas oublier que les nombres de matchs donnés correspondent à un jeu dé-dupliqué.&#xA;&#xA;Conclusion&#xA;&#xA;Et voila, dans la pratique ça nous a permis d&#39;augmenter significativement le nombre d&#39;observations avec des infos d&#39;autochtonie renseignées :&#xA;&#xA;Avant : 15462 en autochtonie possible, 22685 en autochtonie probable, 23466 en autochtonie certaine ;&#xA;Après : 15456 en autochtonie possible, 26492 en autochtonie probable, 33766 en autochtonie certaine, soit +30% !&#xA;&#xA;Comment améliorer la situation ? On voit que certains commentaires essayent de suivre une certaine nomenclature en décrivant les exuvies observées, en ajoutant m et f pour genrer les individus et/ou les exuvies, ce qui donne des entrées comme 2m3f,exuvie pour signaler 2 mâles et 3 femelles. Sont-ce les exuvies qui sont genrées ? Ou des individus observés, auquel on annote qu&#39;il y avait également des exuvies sur le lieu ? Impossible de savoir à moins de contacter l&#39;observateur.&#xA;&#xA;Avec les regex présentées ici, on loupe évidemment une masse de commentaires qui décrivent beaucoup trop de choses, utilisent des abréviations obscures, une syntaxe chaotique, mais vouloir prendre en considération tout ces cas pour un traitement automatisé nécessite un temps que personne n&#39;a ; il y a toujours moyen, théoriquement, d&#39;affiner les regex pour ajouter des cas. Pour les données existantes, la seule solution exhaustive est donc une ✨validation manuelle✨ !&#xA;&#xA;Pour la création de données futures en revanche, la meilleure solution semble être de travailler sur des interfaces qui facilitent au maximum la saisie de données et donner à chaque caractéristique de l&#39;observation des champs clairs, typés et avec des contraintes, pour que l&#39;observateur ait pu tout renseigner aux emplacements adéquats et réserver à la case commentaire sa prose lyrique ou ses souvenirs de pique-nique sur le site de l&#39;observation, mais on n&#39;y est pas encore tout à fait !&#xA;&#xA;Bonus&#xA;&#xA;Des commentaires que j&#39;ai bien aimé même s&#39;ils sont impossible à traiter :&#xA;&#xA;- sur roseaux de l&#39;etang, sortent des exuvies merci pour le haiku&#xA;Filet � papillon / Recherche d�exuvies&#xA;Ma première exuvie... 🥲&#xA;1h de recherche d&#39;exu   exuvie / BAM !!! / exu récoltée et mise en collection dans frigo BAM&#xA;Belle surprise ! bientôt des exuvies dans le 77 ?!! woohoo !&#xA;rem. orig. : beau, solei,l vent , nuages, jour de ponte pour le napolitain, vu 4 tandem en ponte, dont un où le mâle se faisait agresser par 2 orthetrum cancellatum qui lui fonçaient dessus en piquet, j’ai cru que l’un d’eux allait lui arracher la tête, 😨&#xA;1x femelle individu mature (en main)- à valider, aeshna cyanea, remarque : rentre dans la maison et sauvée des chats! me mord le doigt jusqu&#39;à faire saigner, re lachée saine et sauve.- idflr :3125315 🙀&#xA;enfin un imago observé dans ce secteur où une larve et une exuvie ont été trouvées en 2015 et 2016 ! ← mauvaise idée d&#39;écrire dans le commentaire d&#39;une observation des informations à propos d&#39;une autre observation !&#xA;Spectre paisible. détail : , 1x individu mature. remarque : rentre dans le Petit Moulin, avec […] et […], j&#39;ai trouvé aussi une exuvie il y a quelques jours au bord du Lauquet - idbiolovision : 3021488 pareil&#xA;Sympa pendant le pique-nique du WE canoé SfO ! - Nombreuses exuvies trouvées sur la Marne, la découverte nord-77 de 2015 ! woohoo un pique-nique ! 🧺🥪🧃&#xA;entre la Chaise et la D81 --------- Champs importes --------- COMMENTAIR  rÂ‚cupÂ‚ration d&#39;exuvies jCODEETUDE  COEMER jCODESITE  S63 jMETEO  NUAGEUX jTEMPERATUR  25 jVENT  FAIBLE bon allez assez entendu]]&gt;</description>
      <content:encoded><![CDATA[<p>Sur l&#39;<a href="https://atlas-odonates.insectes.org" rel="nofollow">atlas des odonates</a> (libellules et demoiselles), on a une problématique d&#39;incertitude concernant l&#39;autochtonie des espèces sur les mailles où elles ont été observées. Vous n&#39;avez pas forcément besoin de comprendre cette phrase pour lire cet article, tant que vous aimez bien les problématiques de gestion de données et les <a href="https://fr.wikipedia.org/wiki/Expression_r%C3%A9guli%C3%A8re" rel="nofollow">regex</a>. </p>

<h2 id="l-autochtonie-les-exuvies" id="l-autochtonie-les-exuvies">L&#39;autochtonie ? Les exuvies ?</h2>

<p>OK, petit lexique.</p>

<p><em>Atlas</em> : un ensemble de cartes représentant la présence ou non d&#39;espèces sur un territoire donnée, généralement par maille.</p>

<p><em>Maille</em> : une zone, un carré sur la carte. Par exemple en France on utilise souvent des mailles de 10km² tracées avec une projection Lambert93, ce qui donne des mailles identifiables avec un code tel que <code>10kmL93E024N677</code>.</p>

<p><em>Autochtonie</em> : une espèce est autochtone sur un lieu si on peut y observer la reproduction, la ponte, la naissance, etc ; en gros, qu&#39;on ne l&#39;a pas observée juste <em>de passage</em>, comme ça peut arriver avec les odonates qui peuvent se balader loin de leur lieu de naissance et de reproduction.</p>

<p><em>Exuvie</em> : la mue laissée par la larve d&#39;odonate avant qu&#39;elle « émerge » en tant qu&#39;individu adulte. <a href="http://guillaume.doucet.free.fr/doc/Cle_Exuvie_Odonate_debut.pdf" rel="nofollow">Quelques photos dans cette clé d&#39;identification</a>. Si on trouve une exuvie quelque part, c&#39;est donc qu&#39;il y a bien eu émergence d&#39;adulte, et donc que l&#39;espèce observée est autochtone à cet endroit <a href="https://www.researchgate.net/profile/Alexandre-Ruffoni/publication/328789741_Reflexion_sur_l&#39;utilisation_de_l&#39;autochtonie_des_Odonates_a_differentes_echelles_Revue_scientifique_Bourgogne-Franche-Comte_Nature_-_27/links/5c1b6e1f458515a4c7eb2784/Reflexion-sur-lutilisation-de-lautochtonie-des-Odonates-a-differentes-echelles-Revue-scientifique-Bourgogne-Franche-Comte-Nature-27.pdf" rel="nofollow">(Ruffoni, 2018)</a>.</p>

<h2 id="les-données" id="les-données">Les données</h2>

<p>On utilise une extraction <a href="https://openobs.mnhn.fr/" rel="nofollow">OpenObs</a> pour alimenter notre atlas, et ces tables contiennent un champ “Stade de vie” mais celui-ci n&#39;est pas toujours renseigné correctement à cause de l&#39;hétérogénéité des jeux de données et des plateformes de saisie utilisées. Si on regarde bien cependant, l&#39;information peut parfois être retrouvée dans le champ “Commentaires” de l&#39;observation, où l&#39;observateur, parfois le producteur de la donnée, nous gratifie d&#39;informations plus ou moins cryptiques, à propos de l&#39;observation, ou de la météo, ou de son humeur… Dans cet article on va donc se pencher sur ce champ de commentaires et voir comment on peut l&#39;utiliser au mieux pour améliorer les infos d&#39;autochtonie.</p>

<p>Beaucoup des idées ci-dessous proviennent des conseils d&#39;<a href="https://ecoevo.social/@a_monsavoir" rel="nofollow">Alexia</a>, notre géomaticienne avec qui j&#39;ai la joie quotidiennement renouvelée de travailler 😌</p>

<p>Les regex ci-dessous sont au format PCRE2 (PHP 7.3 et plus). J&#39;ai remplacé les noms qui apparaissaient dans les commentaires par <code>[…]</code>.</p>

<h2 id="pourquoi-on-ne-peut-pas-juste-grep-exuvie" id="pourquoi-on-ne-peut-pas-juste-grep-exuvie">Pourquoi on ne peut pas juste <code>grep exuvie</code></h2>

<p>On ne peut pas se baser simplement sur la présence du mot « exuvie » en commentaire d&#39;une observation pour pas mal de raisons.</p>

<p>Déjà parce que parfois, c&#39;est écrit « pas d&#39;exuvies ». OK donc on n&#39;a qu&#39;à faire une regex qui enlève « pas [espace] d&#39;exuvies » ; pourquoi pas mais du coup, attention à ne pas ignorer les gros malins qui ont alors commenté « pas mal d&#39;exuvies » ! Il y a aussi quelques commentaires dans d&#39;autres langues, notamment en allemand : « viele exuvien » (plein), « altere Exuvien » (anciennes), « frische Exuvien » (fraîche), « keine Exuvien » (aucune). Exemples relous :</p>
<ul><li><code>Toutes émergented, pas mal d&#39;exuvies dans les iris</code></li>
<li><code>4 - males uniquement pas trouve d&#39;exuvie Ã  ce jour</code></li>
<li><code>pas encore trouvé d&#39;exuvies</code></li>
<li><code>M et F adultes et 1 M immatures tres tres frais (quasi emergent mais pas vu l&#39;exuvie!). Observations en compagnie de […].</code></li></ul>

<p>Parfois le commentaire est utilisé pour décrire d&#39;autres éléments de l&#39;observation, qui mentionnent le terme d&#39;exuvie mais sans être en rapport avec la quantité d&#39;exuvies trouvées dans l&#39;observation. Quelques exemples :</p>
<ul><li><code>Formation odonate et identification des exuvies organisée par l&#39;ALEPE avec […] et […]</code></li>
<li><code>rem. orig. : B, prospection exuvies, tronçon 2- src : Gard Nature - prot : Observation occasionnelle</code></li>
<li><code>territorialié- id_source : 10923- BDD_exuvies2015_modif_export.xlsx- 20161017</code></li></ul>

<p>À moins de faire une regex particulièrement illisible et constamment incomplète, c&#39;est impossible d&#39;utiliser un modèle de <a href="https://en.wikipedia.org/wiki/Blacklist_(computing)" rel="nofollow">denylist</a> pour vérifier les exuvies, et donc détecter uniquement la présence du mot exuvie n&#39;est pas satisfaisant pour notre besoin ici. On va donc écrire une regex dont on utilisera les matchs pour affirmer la présence d&#39;une exuvie, quitte à avoir des faux négatifs, mais avec presque aucun faux positifs.</p>

<h2 id="détails-astuces-et-mauvaises-idées" id="détails-astuces-et-mauvaises-idées">Détails, astuces et mauvaises idées</h2>

<p>Si on souhaite se restreindre au modèle « [nombre] exuvie », il faut faire attention à ignorer tous les commentaires qui disent gentiment qu&#39;il y a « 0 exuvies » (mais pas ignorer « 10 exuvies » !). Bien entendu c&#39;est parfois écrit en toutes lettres : « Une exuvie », « Trois exuvies », « Quatre exuvies ».</p>

<p>On aimerait bien ignorer les commentaires qui disent « aucune exuvie » ou « pas d&#39;exuvie », mais évidemment des petits malins ont commenté « Pas mal d&#39;exuvies » 😭</p>

<p>On serait tenté de capturer plus de résultat en réduisant la recherche à « exu » car beaucoup de commentaires utilisent « ex » ou « exu » car « exuvie » c&#39;est trop long à écrire j&#39;imagine, mais c&#39;est sans compter la présence de mots comme « exutoire ». On a aussi envie de match les chaînes « exuvies trouvées » ou « exuvies récoltées », mais elles semblent pouvoir apparaître autant dans des affirmations positives que négatives !</p>

<p>Parmi d&#39;autres détails, l&#39;orthographe officielle est « exuvie » mais elle est parfois orthographiée « éxuvie ». Enfin, la gestion de la casse est un problème de tous les instants, et il peut être intéressant de commencer par passer l&#39;entièreté de son jeu de données en minuscules pour simplifier l&#39;écriture des regex ensuite, ou d&#39;ajouter le flag <code>i</code> à ses patterns pour ignorer la casse.</p>

<h2 id="protocole" id="protocole">Protocole</h2>

<h3 id="préparation-des-données" id="préparation-des-données">Préparation des données</h3>

<p>Depuis une extraction d&#39;OpenObs des insectes, préalablement filtrée sur l&#39;ordre Odonata, on extrait les observations dont les commentaires (colonne 80) contiennent le mot « exuvie » avec l&#39;excellent <a href="https://csvkit.readthedocs.io/en/latest/scripts/csvgrep.html" rel="nofollow">csvgrep</a> :</p>

<pre><code class="language-bash">csvgrep
    -c 80 \
    -r &#34;[eEéÉèÈ]xuvie&#34; \
    extractINPN_insectes_21092023_Odonata.csv \
&gt; /tmp/exuvia.csv
</code></pre>

<p>On récupère la liste de ces commentaires dédupliqués et triés pour pouvoir tester nos regex facilement :</p>

<pre><code class="language-bash">… | csvcut -c 80 | sort -u &gt; commentaire_exuvie_uniq.txt
</code></pre>

<p>Ce fichier fait 4306 lignes.</p>

<h3 id="compter-les-commentaires-les-plus-simples" id="compter-les-commentaires-les-plus-simples">Compter les commentaires les plus simples</h3>

<p>Si le commentaire commence par « exuvie », sans compter quelques caractères parasites, alors nous n&#39;avons pas trouvé de contre-exemples au fait que l&#39;observation concerne bel et bien une ou plusieurs exuvies.</p>

<p>Regex : <code>/^[\-\*\+]? *[eé]xuvie/i</code></p>

<p>Rien qu&#39;avec cette regex on a 348 matchs.</p>

<h3 id="repérer-les-comptages-d-exuvies" id="repérer-les-comptages-d-exuvies">Repérer les comptages d&#39;exuvies</h3>

<p>À défaut de pouvoir proprement ignorer les commentaires stipulant qu&#39;il n&#39;y a pas d&#39;exuvies parce qu&#39;on ne sait jamais quand un odonatologue décidera d&#39;annoter dans son patois qu&#39;il n&#39;a vu aucune exuvie, on peut essayer de cibler au mieux la présence d&#39;un certain nombre d&#39;exuvie, que ça soit en chiffres ou en toutes lettres.</p>

<p>Pour les chiffres, sont valides les nombres à un chiffre de 1 à 9, ou n&#39;importe quel chiffre à partir de 2 chiffres par nombre. Théoriquement ça fait que « 00 exuvie » match, mais bon… Attention en revanche à la pattern <code>/une exuvie/</code> car elle match la chaîne « aucune exuvie » 🫠 un petit negative lookbehind est donc de rigueur.</p>

<p>On améliore ses résultats en ignorant certaines qualificatifs comme « ancienne » ou les genres. On détecte les <code>m</code> et <code>f</code>, voire <code>mf</code> qui servent à genrer les nombres, et les <code>x</code> neutres. Comme on est sympa, on match aussi les nombres en toutes lettres (enfin de un à neuf). On trouve également parfois des quantificateurs flous mais utiles, comme « nombreuses exuvies » ou « plusieurs exuvies ».</p>

<p>Regex : <code>/(([0-9]{2,}|[1-9])(x|m|f|mf)?|(?&lt;!auc)une|qq|qlq|quelques|deux|trois|quatre|cinq|six|sept|huit|neuf|nombreuses|plusieurs)([[:blank:]](m[aâ]les?|femelles?|anciennes?|vieilles?))?[[:blank:]]?[eé]xuvie/i</code></p>

<p>Dans le détail :</p>

<pre><code>/(
    ([0-9]{2,}|[1-9])
    (x|m|f|mf)?
|
    (?&lt;!auc)une
|
    qq|qlq|quelques|deux|trois|quatre|cinq|six|sept|huit|neuf|nombreuses|plusieurs
)
([[:blank:]](m[aâ]les?|femelles?|anciennes?|vieilles?))?
[[:blank:]]?[eé]xuvie
/xi
</code></pre>

<p>Tout de suite on passe à 2767 matchs !</p>

<p>En général il semble plus prudent de ne pas supprimer les virgules car on n&#39;est jamais à l&#39;abri d&#39;un naturaliste fou qui aurait écrit « larves 4, exuvies 0 », qu&#39;un filtre trop enthousiaste interprèterait comme « larves 4 exuvies 0 » et bondirait sur « 4 exuvies ». En revanche, s&#39;il n&#39;y a rien après la mention d&#39;exuvie, on peut se permettre de compter dans un match une virgule entre un comptage et le mot exuvie, ce qui permet de match une bonne dizaine de cas supplémentaires.</p>

<p>Regex :</p>

<pre><code>/(([0-9]{2,}|[1-9])(x|m|f|mf)?){1,2},?[[:blank:]]?[eé]xuvies?$/i
                               ^^^^^
                               un ou deux groupes (e.g. 1m, 2f, 3m4f, …)
</code></pre>

<h3 id="quelques-cas-autres-intéressants" id="quelques-cas-autres-intéressants">Quelques cas autres intéressants</h3>

<p>D&#39;autres quantificateurs imprécis mais on notera le « d&#39; » avant le mot exuvie.</p>

<p>Regex : <code>/(dizaines?|centaines?)[[:blank:]]d&#39;[eé]xuvie/i</code></p>

<p>Enfin le mot « présence » est souvent utilisé aussi.</p>

<p>Regex : <code>/pr[eé]sence[[:blank:]](?:d&#39;|de\x20l&#39;)[eé]xuvie/i</code></p>

<p>Ce qui nous fait passer à 2828 matchs.</p>

<h3 id="regex-finale" id="regex-finale">Regex finale</h3>

<pre><code>/(
  ^[\-\*\+]?[[:blank:]]*[eé]xuvie
|
  (([0-9]{2,}|[1-9])(x|m|f|mf)?|(?&lt;!auc)une|qq|qlq|quelques|deux|trois|quatre|cinq|six|sept|huit|neuf|nombreuses|plusieurs)([[:blank:]](m[aâ]les?|femelles?|anciennes?|vieilles?))?[[:blank:]]?[eé]xuvie
|
  (([0-9]{2,}|[1-9])(x|m|f|mf)?){1,2},?[[:blank:]]?[eé]xuvies?$
|
  (dizaines?|centaines?)[[:blank:]]d&#39;[eé]xuvie
|
  pr[eé]sence[[:blank:]](?:d&#39;|de\x20l&#39;)[eé]xuvie
)/xi
</code></pre>

<p>Au final c&#39;est surtout la deuxième partie, où on cherche « [nombre] exuvie » qui rapporte un maximum d&#39;information, en tout cas sur la diversité des commentaires disponibles car il ne faut pas oublier que les nombres de matchs donnés correspondent à un jeu dé-dupliqué.</p>

<h2 id="conclusion" id="conclusion">Conclusion</h2>

<p>Et voila, dans la pratique ça nous a permis d&#39;augmenter significativement le nombre d&#39;observations avec des infos d&#39;autochtonie renseignées :</p>
<ul><li>Avant : 15462 en autochtonie possible, 22685 en autochtonie probable, 23466 en autochtonie certaine ;</li>
<li>Après : 15456 en autochtonie possible, 26492 en autochtonie probable, 33766 en autochtonie certaine, soit +30% !</li></ul>

<p>Comment améliorer la situation ? On voit que certains commentaires essayent de suivre une certaine nomenclature en décrivant les exuvies observées, en ajoutant m et f pour genrer les individus et/ou les exuvies, ce qui donne des entrées comme <code>2m3f,exuvie</code> pour signaler 2 mâles et 3 femelles. Sont-ce les exuvies qui sont genrées ? Ou des individus observés, auquel on annote qu&#39;il y avait également des exuvies sur le lieu ? Impossible de savoir à moins de contacter l&#39;observateur.</p>

<p>Avec les regex présentées ici, on loupe évidemment une masse de commentaires qui décrivent beaucoup trop de choses, utilisent des abréviations obscures, une syntaxe chaotique, mais vouloir prendre en considération tout ces cas pour un traitement automatisé nécessite un temps que personne n&#39;a ; il y a toujours moyen, <em>théoriquement</em>, d&#39;affiner les regex pour ajouter des cas. Pour les données existantes, la seule solution exhaustive est donc une ✨validation manuelle✨ !</p>

<p>Pour la création de données futures en revanche, la meilleure solution semble être de travailler sur des interfaces qui facilitent au maximum la saisie de données et donner à chaque caractéristique de l&#39;observation des champs clairs, typés et avec des contraintes, pour que l&#39;observateur ait pu tout renseigner aux emplacements adéquats et réserver à la case commentaire sa prose lyrique ou ses souvenirs de pique-nique sur le site de l&#39;observation, mais on n&#39;y est pas encore tout à fait !</p>

<h2 id="bonus" id="bonus">Bonus</h2>

<p>Des commentaires que j&#39;ai bien aimé même s&#39;ils sont impossible à traiter :</p>
<ul><li><code>- sur roseaux de l&#39;etang, sortent des exuvies</code> merci pour le haiku</li>
<li><code>Filet � papillon / Recherche d�exuvies</code></li>
<li><code>Ma première exuvie...</code> 🥲</li>
<li><code>1h de recherche d&#39;exu   exuvie / BAM !!! / exu récoltée et mise en collection dans frigo</code> BAM</li>
<li><code>Belle surprise ! bientôt des exuvies dans le 77 ?!!</code> woohoo !</li>
<li><code>rem. orig. : beau, solei,l vent , nuages, jour de ponte pour le napolitain, vu 4 tandem en ponte, dont un où le mâle se faisait agresser par 2 orthetrum cancellatum qui lui fonçaient dessus en piquet, j’ai cru que l’un d’eux allait lui arracher la tête,</code> 😨</li>
<li><code>1x femelle individu mature (en main)- à valider, aeshna cyanea, remarque : rentre dans la maison et sauvée des chats! me mord le doigt jusqu&#39;à faire saigner, re lachée saine et sauve.- id_flr :3125315</code> 🙀</li>
<li><code>enfin un imago observé dans ce secteur où une larve et une exuvie ont été trouvées en 2015 et 2016 !</code> ← mauvaise idée d&#39;écrire dans le commentaire d&#39;une observation des informations à propos d&#39;une autre observation !</li>
<li><code>Spectre paisible. détail : , 1x individu mature. remarque : rentre dans le Petit Moulin, avec […] et […], j&#39;ai trouvé aussi une exuvie il y a quelques jours au bord du Lauquet - id_biolovision : 3021488</code> pareil</li>
<li><code>Sympa pendant le pique-nique du WE canoé SfO ! - Nombreuses exuvies trouvées sur la Marne, la découverte nord-77 de 2015 !</code> woohoo un pique-nique ! 🧺🥪🧃</li>
<li><code>entre la Chaise et la D81 --------- Champs importes --------- COMMENTAIR  rÂ‚cupÂ‚ration d&#39;exuvies j_CODE_ETUDE  COEMER j_CODE_SITE  S63 j_METEO  NUAGEUX j_TEMPERATUR  25 j_VENT  FAIBLE</code> bon allez assez entendu</li></ul>
]]></content:encoded>
      <guid>https://textes.pistache.land/dece/ameliorer-des-donnees-dautochtonie-dodonates-a-coups-de-regex</guid>
      <pubDate>Tue, 27 Feb 2024 17:53:20 +0100</pubDate>
    </item>
    <item>
      <title>Lectures de 2023</title>
      <link>https://textes.pistache.land/dece/lectures-de-2023</link>
      <description>&lt;![CDATA[Par manque de temps j&#39;ai écrit ma liste de lectures, habituellement destinée à ma capsule Gemini, en français, et ça m&#39;embête de poster du contenu non traduit là-bas, et d&#39;un autre côté je suis content d&#39;alimenter cette instance WriteFreely où Laërte et Mystr (en privé) postent déjà du contenu in·cro·yable, donc je pose ça ici pour l&#39;instant. !--more--&#xA;&#xA;Baptiste Morizot : Manières d&#39;être vivant&#xA;&#xA;Introduction : la crise écologique comme crise de la sensibilité&#xA;Une saison chez les vivants&#xA;Les promesses d&#39;une éponge&#xA;Cohabiter avec ses fauves&#xA;Passer de l&#39;autre côté de la nuit&#xA;Épilogue : les égards ajustés (par Alain Damasio)&#xA;&#xA;Le premier texte mêle une histoire de pistage de loups dans le Vercors avec un essai sur les communs de l&#39;être humain et de ce qu&#39;on appelle la nature, ou les animaux. Un passage notamment traite du fait qu&#39;appeler les autres animaux tel quel, avec ce terme &#34;autre&#34; permet de souligner notre appartenance à un même groupe.&#xA;&#xA;Le second texte traite plus d&#39;évolution. Il passe sur un débat intéressant entre l&#39;évolution qui serait d&#39;une part un pur fruit du hasard, et de l&#39;autre une mécanique qui tendrait forcément vers l&#39;homme, jusqu&#39;à une perfection qu&#39;on ne connaît pas encore ; il présente la théorie plus prometteuse et a priori respectée aujourd&#39;hui parmi les scientifiques que l&#39;évolution par certains caractères se fait parce qu&#39;ils sont simplement avantageux quoi qu&#39;il en soit : les yeux, la photosynthèse, une forme d&#39;intelligence, etc, et on peut le démontrer notamment par le fait que ces caractères ont été développés en parallèle par plusieurs organismes, et non pas par un individu unique quelque part dans l&#39;évolution des espèces, e.g. la photosynthèse qui aurait été développée plus de cent fois indépendamment.&#xA;&#xA;Le troisième texte est un vaste appel à lire Spinoza.&#xA;&#xA;Le quatrième texte raconte l&#39;expérience de l&#39;auteur comme observateur au sein d&#39;un projet de supervision des relations entre les éleveurs, leur bétail, leurs chiens, les loups et les chasseurs. Leurs interactions sont d&#39;une complexité proprement passionnante et permettent à l&#39;auteur de tracer les lignes de la pièce manquante de nos sociétés, la diplomatie entre les espèces.&#xA;&#xA;L&#39;épilogue est du pur Damasio.&#xA;&#xA;C&#39;est une lecture très agréable et j&#39;y ai appris pas mal de choses, mais je me posais quelques questions d&#39;efficicaté politique—surtout après la lecture de l&#39;article de Joseph Confavreux « Le “vivant” noie-t-il le poisson politique ? »—que je voulais poser quelque part sur papier et j&#39;ai oublié.&#xA;&#xA;Frédéric Beigbeder : 99 francs&#xA;&#xA;Une histoire de publicitaire qui pète les plombs. Le livre est écrit comme un roman dont le côté autobiographique est volontairement à peine dissimulé : le personnage écrit un livre pour se faire virer du milieu de la pub, car c&#39;est ce que l&#39;auteur faisait en écrivant ce livre ; méta !&#xA;&#xA;Il y a des bonnes idées mais c&#39;est vraiment une narration de mec de droite qui pense surpasser sa condition de mec de droite ; il y a une scène où les personnages vont tabasser une retraitée de Floride dont les thunes sont probablement dans les larges fonds de pension américains, avec une rhétorique de gauchiste maladroite. L&#39;auteur est étrangement fasciné par l&#39;omnipotence de la publicité et de ce qui serait son pouvoir absolu sur les gens, jusqu&#39;à ce que se confonde la critique et une admiration à peine voilée. C&#39;est aussi très vulgaire sans justification.&#xA;&#xA;Virginie Despentes : King Kong théorie&#xA;&#xA;Virginie Despentes parle de sa conception du féminisme, raconte sa jeunesse, son intimité, son viol, sa prostitution. Un article de Camille Paglia l&#39;encourage à considérer son viol comme étant une conséquence du risque qu&#39;il y a à sortir comme femme libre, et non comme une honte à garder sous silence.&#xA;&#xA;L&#39;essai constitue une porte d&#39;entrée spéciale sur le féminisme et je le recommande à quiconque souhaitant de nouvelles perspectives sur le sujet. Ça m&#39;a beaucoup plu.&#xA;&#xA;Virginie Despentes : Baise-moi&#xA;&#xA;Nadine et Manu se retrouvent simultanément dépourvues de quoi que ce soit à perdre et partent en cavale pour accomplir personne ne sait trop quoi ; expérimenter une jouissance crue et sans compromis sur les routes de France, dont les seuls constantes seront l&#39;alcool, le sexe et le meurtre.&#xA;&#xA;C&#39;est le premier roman de Despentes, dont est issu un film sorti en 2000 qui a été censuré en France. Si on connaît les films God Bless America ou The Devil&#39;s Rejects, c&#39;est assez ouf de constater à quel point ce roman possédait déjà tout. C&#39;est plus dur et froid que d&#39;autres romans plus connus de Despentes comme Vernon Subutex, il y a beaucoup de scènes de violence, une scène de viol, plusieurs meurtres notamment envers des personnages qu&#39;on n&#39;est pas habitué à voir tués.&#xA;&#xA;C&#39;est aisément mon roman trash préféré (OK je connais que lui) mais je ne le conseille qu&#39;aux cœurs bien accrochés. La fin est stylée ! 💯&#xA;&#xA;John Fante : Demande à la poussière&#xA;&#xA;Les aventures de Bandini, aspirant écrivain avec un goût immodéré pour les femmes, l&#39;alcool et le scandale, il me fait un peu penser à un copain mais je dirais pas qui. On suit sa vie à Los Angeles, son histoire d&#39;amour avec Camilla la serveuse d&#39;un bar, leurs disputes et leur incapacité à communiquer leurs sentiments. Le désert de Californie est toujours là en train de les menacer de les engloutir sous sa poussière. C&#39;est un roman poignant, à la fois drôle et amer. Ce style crypto-autobiographique où l&#39;on fait comme si on n&#39;écrivait pas sa propre histoire me plaît beaucoup et j&#39;espère avec l&#39;occasion de lire d&#39;autres livres de Fante.&#xA;&#xA;Charles Bukowski : Le postier&#xA;&#xA;L&#39;histoire d&#39;un postier et de ses conditions de travail. Quand les personnages crient, il écrit en majuscule et je trouve ça très appréciable. Bukowski est un peu trop obsédé par le cul, des fois c&#39;est un peu gênant, mais ça a son sens comme échappatoire à l&#39;enfer du taf. Il y a une bonne dose d&#39;humour amer, notamment la scène de cul avec les pots de géraniums qui tombent mais j&#39;en dis pas plus. Attention tout de même des fois ça va trop loin et il y a une scène de viol tout à fait assumée que j&#39;ai trouvé dure à lire.&#xA;&#xA;Mircea Eliade : Le sacré et le profane&#xA;&#xA;Petite introduction à l&#39;étude phénoménologique et historique des faits religieux. On y apprend notamment comment les rituels comme le ramadan ou les rituels saisonnier servent à reproduire un temps originel, sacré, pour ramener à l&#39;existence profane, c&#39;est à dire hors des phénomènes divins, une présence sacrée. On retrouve ce besoin d&#39;amener le sacré également dans les manières d&#39;établir un nouveau village (feu central), dans l&#39;architecture et l&#39;aménagement des maisons.&#xA;&#xA;En tant qu&#39;athée, ce livre m&#39;a permis de mieux saisir comment les personnes religieuses perçoivent l&#39;univers autour d&#39;eux, leur « cosmos », et d&#39;y trouver des similarités avec mes propres habitudes et approches du monde. Il est sans doute utile de préciser que les travaux d&#39;Eliade, même s&#39;ils sont reconnus, sont toujours sujets à de vives critiques donc tout est à prendre avec des pincettes, et en plus c&#39;était sans doute un gros facho. Une critique revenant souvent est que les thèses présentées sont très réductrices, et qu&#39;il ne suffit pas de répéter qu&#39;il ne s&#39;agit que d&#39;une introduction à un vaste champ d&#39;études pour expliquer comment des cultures aux histoires si variées soient si facilement assimilées.&#xA;&#xA;Chapitres :&#xA;&#xA;L&#39;espace sacré et la sacralisation du Monde&#xA;Le Temps sacré et les mythes&#xA;La sacralité de la Nature et la religion cosmique&#xA;Existence humaine et vie sanctifiée&#xA;&#xA;Andrzej Sapkowski : Le Sorceleur (livre 1)&#xA;&#xA;Un recueil de nouvelles fantastiques sur les aventures de Geralt de Riv, un sorceleur. C&#39;est ce personnage et ses histoires qui donna lieu à la série de jeux vidéo The Witcher. Le monde est habité par tous les éléments du corpus habituel des mondes de fantasy occidentaux, avec l&#39;ajout de monstres spécifiques à la culture slave, notamment des kikomoras), des bruxæ, etc. Les histoires sont plutôt sympas à suivre, avec plein de rebondissements, les personnages s&#39;étoffent petit à petit et le monde se dévoile (sans trop de surprises). Le style est OK, ma plus grosse critique serait qu&#39;on sent un regard un peu lubrique de l&#39;auteur sur ses personnages féminins, avec des scènes érotiques servant bien peu le récit.&#xA;&#xA;William Faulkner : Le bruit et la fureur&#xA;&#xA;Un récit chaotique d&#39;une famille en totale déliquescence. On suit le monologue interne de quatre personnages différents pendant quatre parties du livre, avec chacun une façon différente de brouiller le récit, par des sauts dans le temps constants, genre tous les paragraphes, ou d&#39;absence de ponctuation, ou en étant tout simplement un personnage inapte à réfléchir normalement.&#xA;&#xA;J&#39;ai eu beaucoup de mal au début et au milieu et à la fin ça allait mieux mais je suis pas sûr de pourquoi je me suis infligé tout ça. Pour l&#39;expérience stylistique de la perte de repères ?&#xA;&#xA;Bernard Friot : Vaincre Macron&#xA;&#xA;Un exposé de ses thèses sur la question des retraites, la principale étant que la gestion des caisses de retraite, amenée en 1946 par Ambroise Croizat et le CNR au sein du projet global de Sécurité Sociale, par les travailleurs eux-mêmes constitue un « déjà-là communiste » sur lequel il faut capitaliser (🤣) pour lutter vers un salaire à vie et ne rien lâcher de ce que nous possédons en sécurité social.&#xA;&#xA;Bon, moi je suis déjà assez conquis à ses propositions, mais j&#39;ai trouvé très dommage qu&#39;il attende la toute fin du livre pour répondre à la question, qui ne manque pourtant jamais de tomber, du financement d&#39;un tel changement de paradigme dans le partage des ressources par l&#39;évidence même que serait l&#39;appropriation des moyens de production. Mais oui c&#39;est vrai, qu&#39;est-ce qu&#39;on attend après tout ? À ce stade on serait pas mieux d&#39;abolir l&#39;argent du coup ? La valeur ? À part ça c&#39;est assez fastidieux à lire, il faut vraiment vouloir en apprendre un rayon sur les nuances entre les différents systèmes de caisses de retraite—ce qui n&#39;est pas mon cas, d&#39;ailleurs j&#39;ai à peu près tout oublié—ce qui ne facilite pas la diffusion des idées de Friot que je juge par ailleurs comme tout à fait pertinentes et révolutionnaires.&#xA;&#xA;Joseph Conrad : Typhon&#xA;&#xA;C&#39;est un capitaine, à mon avis sur le spectre autistique, qui dirige un bateau au sein d&#39;une épique tempête en mer. C&#39;est INCROYABLE ! Et très court, franchement foncez ! Et après allez jouer à Return of the Obra Dinn ! 🌊⛵&#xA;&#xA;David Graeber &amp; David Wengrow : Au commencement était…&#xA;&#xA;Un colossal essai entre Graeber l&#39;anthropologue et Wengrow l&#39;archéologue, impossible à résumer, mais ré-articulant de mille manières la question du commencement dans l&#39;humanité : qui étaient ces ancêtres chasseurs-cueilleurs, quels sont les stades d&#39;évolution d&#39;une société, l&#39;état-nation est-il inexorable, après tout le capitaliste n&#39;est-il pas le parfait aboutiss-OH du calme là ! La réponse est souvent à rebours de nos conceptions, et elle est copieusement argumentée et ponctuées d&#39;anecdotes qui font tenir sur un voyage dans les humanités qui peut vite faire tourner la tête et se sentir perdu. Il n&#39;y avait à peu près pas de tribus primitives de chasseurs-cueilleurs nomades qui se seraient sédentarisés, les sociétés n&#39;ont presque jamais évolué de façon réellement similaire, l&#39;état-nation ne saurait être qu&#39;une parenthèse de l&#39;histoire. Bon ça c&#39;est moi qui projette.&#xA;&#xA;Honnêtement, je me suis totalement senti perdu. Mais ça n&#39;est pas bien important car les thèses avancées sont souvent présentées plusieurs fois, pour leur permettre de se corroborer et d&#39;ancrer ce qui est je pense le plus important pour le lecteur profane, c&#39;est à dire l&#39;idée qu&#39;il n&#39;y a pas, dans l&#39;histoire de l&#39;humanité, un commencement mais une profusion d&#39;histoires dont nous n&#39;avons que rarement idée de la richesse et de la diversité, que voir notre passé à l&#39;aune du Capitalocène n&#39;est souvent pertinent que pour les capitalistes, et en ça c&#39;est un ouvrage passionnant !&#xA;&#xA;John Steinbeck : La perle&#xA;&#xA;Un pêcheur d&#39;une famille très modeste tombe sur un perle incroyable, mais sa quête pour transformer la providence en prospérité pour sa femme et son fils ne sera pas sans embûches. Bon j&#39;ai vraiment pas trop aimé, alors que j&#39;ai adoré Des souris et des hommes, c&#39;est très… simple, creux et lourd à la fois ?&#xA;&#xA;- -&#xA;&#xA;J&#39;ai malheureusement abandonné par manque de temps, bien que c&#39;étaient d&#39;excellentes lectures :&#xA;&#xA;Rosemary Sayigh : The Palestinians: From Peasants to Revolutionaries&#xA;Prosper-Olivier Lissagaray : Histoire de la commune de 1871&#xA;&#xA;lectures]]&gt;</description>
      <content:encoded><![CDATA[<p>Par manque de temps j&#39;ai écrit ma liste de lectures, habituellement destinée à ma capsule Gemini, en français, et ça m&#39;embête de poster du contenu non traduit là-bas, et d&#39;un autre côté je suis content d&#39;alimenter cette instance WriteFreely où Laërte et Mystr (en privé) postent déjà du contenu in·cro·yable, donc je pose ça ici pour l&#39;instant. </p>

<h2 id="baptiste-morizot-manières-d-être-vivant" id="baptiste-morizot-manières-d-être-vivant">Baptiste Morizot : Manières d&#39;être vivant</h2>
<ul><li>Introduction : la crise écologique comme crise de la sensibilité</li>
<li>Une saison chez les vivants</li>
<li>Les promesses d&#39;une éponge</li>
<li>Cohabiter avec ses fauves</li>
<li>Passer de l&#39;autre côté de la nuit</li>
<li>Épilogue : les égards ajustés (par Alain Damasio)</li></ul>

<p>Le premier texte mêle une histoire de pistage de loups dans le Vercors avec un essai sur les communs de l&#39;être humain et de ce qu&#39;on appelle la nature, ou les animaux. Un passage notamment traite du fait qu&#39;appeler les autres animaux tel quel, avec ce terme “autre” permet de souligner notre appartenance à un même groupe.</p>

<p>Le second texte traite plus d&#39;évolution. Il passe sur un débat intéressant entre l&#39;évolution qui serait d&#39;une part un pur fruit du hasard, et de l&#39;autre une mécanique qui tendrait forcément vers l&#39;homme, jusqu&#39;à une perfection qu&#39;on ne connaît pas encore ; il présente la théorie plus prometteuse et a priori respectée aujourd&#39;hui parmi les scientifiques que l&#39;évolution par certains caractères se fait parce qu&#39;ils sont simplement avantageux quoi qu&#39;il en soit : les yeux, la photosynthèse, une forme d&#39;intelligence, etc, et on peut le démontrer notamment par le fait que ces caractères ont été développés en parallèle par plusieurs organismes, et non pas par un individu unique quelque part dans l&#39;évolution des espèces, e.g. la photosynthèse qui aurait été développée plus de cent fois indépendamment.</p>

<p>Le troisième texte est un vaste appel à lire Spinoza.</p>

<p>Le quatrième texte raconte l&#39;expérience de l&#39;auteur comme observateur au sein d&#39;un projet de supervision des relations entre les éleveurs, leur bétail, leurs chiens, les loups et les chasseurs. Leurs interactions sont d&#39;une complexité proprement passionnante et permettent à l&#39;auteur de tracer les lignes de la pièce manquante de nos sociétés, la diplomatie entre les espèces.</p>

<p>L&#39;épilogue est du pur Damasio.</p>

<p>C&#39;est une lecture très agréable et j&#39;y ai appris pas mal de choses, mais je me posais quelques questions d&#39;efficicaté politique—surtout après la lecture de l&#39;article de Joseph Confavreux <a href="https://www.mediapart.fr/journal/culture-et-idees/210523/le-vivant-noie-t-il-le-poisson-politique" rel="nofollow">« Le “vivant” noie-t-il le poisson politique ? »</a>—que je voulais poser quelque part sur papier et j&#39;ai oublié.</p>

<h2 id="frédéric-beigbeder-99-francs" id="frédéric-beigbeder-99-francs">Frédéric Beigbeder : 99 francs</h2>

<p>Une histoire de publicitaire qui pète les plombs. Le livre est écrit comme un roman dont le côté autobiographique est volontairement à peine dissimulé : le personnage écrit un livre pour se faire virer du milieu de la pub, car c&#39;est ce que l&#39;auteur faisait en écrivant ce livre ; méta !</p>

<p>Il y a des bonnes idées mais c&#39;est vraiment une narration de mec de droite qui pense surpasser sa condition de mec de droite ; il y a une scène où les personnages vont tabasser une retraitée de Floride dont les thunes sont probablement dans les larges fonds de pension américains, avec une rhétorique de gauchiste maladroite. L&#39;auteur est étrangement fasciné par l&#39;omnipotence de la publicité et de ce qui serait son pouvoir absolu sur les gens, jusqu&#39;à ce que se confonde la critique et une admiration à peine voilée. C&#39;est aussi très vulgaire sans justification.</p>

<h2 id="virginie-despentes-king-kong-théorie" id="virginie-despentes-king-kong-théorie">Virginie Despentes : King Kong théorie</h2>

<p>Virginie Despentes parle de sa conception du féminisme, raconte sa jeunesse, son intimité, son viol, sa prostitution. Un article de Camille Paglia l&#39;encourage à considérer son viol comme étant une conséquence du risque qu&#39;il y a à sortir comme femme libre, et non comme une honte à garder sous silence.</p>

<p>L&#39;essai constitue une porte d&#39;entrée spéciale sur le féminisme et je le recommande à quiconque souhaitant de nouvelles perspectives sur le sujet. Ça m&#39;a beaucoup plu.</p>

<h2 id="virginie-despentes-baise-moi" id="virginie-despentes-baise-moi">Virginie Despentes : Baise-moi</h2>

<p>Nadine et Manu se retrouvent simultanément dépourvues de quoi que ce soit à perdre et partent en cavale pour accomplir personne ne sait trop quoi ; expérimenter une jouissance crue et sans compromis sur les routes de France, dont les seuls constantes seront l&#39;alcool, le sexe et le meurtre.</p>

<p>C&#39;est le premier roman de Despentes, dont est issu un film sorti en 2000 qui a été censuré en France. Si on connaît les films God Bless America ou The Devil&#39;s Rejects, c&#39;est assez ouf de constater à quel point ce roman possédait déjà tout. C&#39;est plus dur et froid que d&#39;autres romans plus connus de Despentes comme Vernon Subutex, il y a beaucoup de scènes de violence, une scène de viol, plusieurs meurtres notamment envers des personnages qu&#39;on n&#39;est pas habitué à voir tués.</p>

<p>C&#39;est aisément mon roman trash préféré (OK je connais que lui) mais je ne le conseille qu&#39;aux cœurs bien accrochés. La fin est stylée ! 💯</p>

<h2 id="john-fante-demande-à-la-poussière" id="john-fante-demande-à-la-poussière">John Fante : Demande à la poussière</h2>

<p>Les aventures de Bandini, aspirant écrivain avec un goût immodéré pour les femmes, l&#39;alcool et le scandale, il me fait un peu penser à un copain mais je dirais pas qui. On suit sa vie à Los Angeles, son histoire d&#39;amour avec Camilla la serveuse d&#39;un bar, leurs disputes et leur incapacité à communiquer leurs sentiments. Le désert de Californie est toujours là en train de les menacer de les engloutir sous sa poussière. C&#39;est un roman poignant, à la fois drôle et amer. Ce style crypto-autobiographique où l&#39;on fait comme si on n&#39;écrivait pas sa propre histoire me plaît beaucoup et j&#39;espère avec l&#39;occasion de lire d&#39;autres livres de Fante.</p>

<h2 id="charles-bukowski-le-postier" id="charles-bukowski-le-postier">Charles Bukowski : Le postier</h2>

<p>L&#39;histoire d&#39;un postier et de ses conditions de travail. Quand les personnages crient, il écrit en majuscule et je trouve ça très appréciable. Bukowski est un peu trop obsédé par le cul, des fois c&#39;est un peu gênant, mais ça a son sens comme échappatoire à l&#39;enfer du taf. Il y a une bonne dose d&#39;humour amer, notamment la scène de cul avec les pots de géraniums qui tombent mais j&#39;en dis pas plus. Attention tout de même des fois ça va trop loin et il y a une scène de viol tout à fait assumée que j&#39;ai trouvé dure à lire.</p>

<h2 id="mircea-eliade-le-sacré-et-le-profane" id="mircea-eliade-le-sacré-et-le-profane">Mircea Eliade : Le sacré et le profane</h2>

<p>Petite introduction à l&#39;étude phénoménologique et historique des faits religieux. On y apprend notamment comment les rituels comme le ramadan ou les rituels saisonnier servent à reproduire un temps originel, sacré, pour ramener à l&#39;existence profane, c&#39;est à dire hors des phénomènes divins, une présence sacrée. On retrouve ce besoin d&#39;amener le sacré également dans les manières d&#39;établir un nouveau village (feu central), dans l&#39;architecture et l&#39;aménagement des maisons.</p>

<p>En tant qu&#39;athée, ce livre m&#39;a permis de mieux saisir comment les personnes religieuses perçoivent l&#39;univers autour d&#39;eux, leur « cosmos », et d&#39;y trouver des similarités avec mes propres habitudes et approches du monde. Il est sans doute utile de préciser que les travaux d&#39;Eliade, même s&#39;ils sont reconnus, sont toujours sujets à de vives critiques donc tout est à prendre avec des pincettes, et en plus <a href="https://en.wikipedia.org/wiki/Mircea_Eliade#Controversy:_antisemitism_and_links_with_the_Iron_Guard" rel="nofollow">c&#39;était sans doute un gros facho</a>. Une critique revenant souvent est que les thèses présentées sont très réductrices, et qu&#39;il ne suffit pas de répéter qu&#39;il ne s&#39;agit que d&#39;une introduction à un vaste champ d&#39;études pour expliquer comment des cultures aux histoires si variées soient si facilement assimilées.</p>

<p>Chapitres :</p>
<ol><li>L&#39;espace sacré et la sacralisation du Monde</li>
<li>Le Temps sacré et les mythes</li>
<li>La sacralité de la Nature et la religion cosmique</li>
<li>Existence humaine et vie sanctifiée</li></ol>

<h2 id="andrzej-sapkowski-le-sorceleur-livre-1" id="andrzej-sapkowski-le-sorceleur-livre-1">Andrzej Sapkowski : Le Sorceleur (livre 1)</h2>

<p>Un recueil de nouvelles fantastiques sur les aventures de Geralt de Riv, un sorceleur. C&#39;est ce personnage et ses histoires qui donna lieu à la série de jeux vidéo The Witcher. Le monde est habité par tous les éléments du corpus habituel des mondes de <em>fantasy</em> occidentaux, avec l&#39;ajout de monstres spécifiques à la culture slave, notamment des <a href="https://fr.wikipedia.org/wiki/Kikimora_(mythologie)" rel="nofollow">kikomoras</a>, des <a href="https://witcher.fandom.com/wiki/Bruxa" rel="nofollow">bruxæ</a>, etc. Les histoires sont plutôt sympas à suivre, avec plein de rebondissements, les personnages s&#39;étoffent petit à petit et le monde se dévoile (sans trop de surprises). Le style est OK, ma plus grosse critique serait qu&#39;on sent un regard un peu lubrique de l&#39;auteur sur ses personnages féminins, avec des scènes érotiques servant bien peu le récit.</p>

<h2 id="william-faulkner-le-bruit-et-la-fureur" id="william-faulkner-le-bruit-et-la-fureur">William Faulkner : Le bruit et la fureur</h2>

<p>Un récit chaotique d&#39;une famille en totale déliquescence. On suit le monologue interne de quatre personnages différents pendant quatre parties du livre, avec chacun une façon différente de brouiller le récit, par des sauts dans le temps constants, genre tous les paragraphes, ou d&#39;absence de ponctuation, ou en étant tout simplement un personnage inapte à réfléchir normalement.</p>

<p>J&#39;ai eu beaucoup de mal au début et au milieu et à la fin ça allait mieux mais je suis pas sûr de pourquoi je me suis infligé tout ça. Pour l&#39;expérience stylistique de la perte de repères ?</p>

<h2 id="bernard-friot-vaincre-macron" id="bernard-friot-vaincre-macron">Bernard Friot : Vaincre Macron</h2>

<p>Un exposé de ses thèses sur la question des retraites, la principale étant que la gestion des caisses de retraite, amenée en 1946 par Ambroise Croizat et le CNR au sein du projet global de Sécurité Sociale, par les travailleurs eux-mêmes constitue un « déjà-là communiste » sur lequel il faut capitaliser (🤣) pour lutter vers un salaire à vie et ne rien lâcher de ce que nous possédons en sécurité social.</p>

<p>Bon, moi je suis déjà assez conquis à ses propositions, mais j&#39;ai trouvé très dommage qu&#39;il attende la toute fin du livre pour répondre à la question, qui ne manque pourtant jamais de tomber, du financement d&#39;un tel changement de paradigme dans le partage des ressources par l&#39;évidence même que serait l&#39;appropriation des moyens de production. Mais oui c&#39;est vrai, qu&#39;est-ce qu&#39;on attend après tout ? À ce stade on serait pas mieux d&#39;abolir l&#39;argent du coup ? La valeur ? À part ça c&#39;est assez fastidieux à lire, il faut vraiment vouloir en apprendre un rayon sur les nuances entre les différents systèmes de caisses de retraite—ce qui n&#39;est pas mon cas, d&#39;ailleurs j&#39;ai à peu près tout oublié—ce qui ne facilite pas la diffusion des idées de Friot que je juge par ailleurs comme tout à fait pertinentes et révolutionnaires.</p>

<h2 id="joseph-conrad-typhon" id="joseph-conrad-typhon">Joseph Conrad : Typhon</h2>

<p>C&#39;est un capitaine, à mon avis sur le spectre autistique, qui dirige un bateau au sein d&#39;une épique tempête en mer. C&#39;est INCROYABLE ! Et très court, franchement foncez ! Et après allez jouer à Return of the Obra Dinn ! 🌊⛵</p>

<h2 id="david-graeber-david-wengrow-au-commencement-était" id="david-graeber-david-wengrow-au-commencement-était">David Graeber &amp; David Wengrow : Au commencement était…</h2>

<p>Un colossal essai entre Graeber l&#39;anthropologue et Wengrow l&#39;archéologue, impossible à résumer, mais ré-articulant de mille manières la question du commencement dans l&#39;humanité : qui étaient ces ancêtres chasseurs-cueilleurs, quels sont les stades d&#39;évolution d&#39;une société, l&#39;état-nation est-il inexorable, après tout le capitaliste n&#39;est-il pas le parfait aboutiss-OH du calme là ! La réponse est souvent à rebours de nos conceptions, et elle est copieusement argumentée et ponctuées d&#39;anecdotes qui font tenir sur un voyage dans les humanités qui peut vite faire tourner la tête et se sentir perdu. Il n&#39;y avait à peu près pas de tribus primitives de chasseurs-cueilleurs nomades qui se seraient sédentarisés, les sociétés n&#39;ont presque jamais évolué de façon réellement similaire, l&#39;état-nation ne saurait être qu&#39;une parenthèse de l&#39;histoire. Bon ça c&#39;est moi qui projette.</p>

<p>Honnêtement, je me suis totalement senti perdu. Mais ça n&#39;est pas bien important car les thèses avancées sont souvent présentées plusieurs fois, pour leur permettre de se corroborer et d&#39;ancrer ce qui est je pense le plus important pour le lecteur profane, c&#39;est à dire l&#39;idée qu&#39;il n&#39;y a pas, dans l&#39;histoire de l&#39;humanité, <em>un commencement</em> mais <em>une profusion d&#39;histoires</em> dont nous n&#39;avons que rarement idée de la richesse et de la diversité, que voir notre passé à l&#39;aune du Capitalocène n&#39;est souvent pertinent que pour les capitalistes, et en ça c&#39;est un ouvrage passionnant !</p>

<h2 id="john-steinbeck-la-perle" id="john-steinbeck-la-perle">John Steinbeck : La perle</h2>

<p>Un pêcheur d&#39;une famille très modeste tombe sur un perle incroyable, mais sa quête pour transformer la providence en prospérité pour sa femme et son fils ne sera pas sans embûches. Bon j&#39;ai vraiment pas trop aimé, alors que j&#39;ai adoré Des souris et des hommes, c&#39;est très… simple, creux et lourd à la fois ?</p>

<hr>

<p>J&#39;ai malheureusement abandonné par manque de temps, bien que c&#39;étaient d&#39;excellentes lectures :</p>
<ul><li>Rosemary Sayigh : The Palestinians: From Peasants to Revolutionaries</li>
<li>Prosper-Olivier Lissagaray : Histoire de la commune de 1871</li></ul>

<p><a href="/dece/tag:lectures" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">lectures</span></a></p>
]]></content:encoded>
      <guid>https://textes.pistache.land/dece/lectures-de-2023</guid>
      <pubDate>Sun, 25 Feb 2024 00:18:42 +0100</pubDate>
    </item>
  </channel>
</rss>