ICS : Parser un fichier ICS => suppression d'espaces s'il y a des retours à la ligne

Eléphanteau du PHP | 11 Messages

22 juil. 2024, 21:21

Bonjour,

Je viens avec un souci pour lequel je n'ai trouvé de solution ni sur le Github du propriétaire du parser (envoi de mail avec explication il y a deux mois).

J'utilise donc un parser un fichier ICS et l'enregistrer dans une base de données : https://github.com/MartinThoma/ics-parser à l'aide d'une commande CRON.

Jusque là, le parser actuel me donnait un bon résultat sauf... que lorsque le fichier ICS contient des descriptions, et qu'il y a un retour à la ligne dans ces descriptions (retours à la ligne obligés dans le fichier même et non un retour à la ligne voulu dans le texte, cf capture d'écran d'un fichier exemple), l'espace entre les deux mots avant et après à la ligne est carrément supprimé, ici, l'espace entre "it was" et "decided" est supprimé.
Image

J'utilise un subterfuge en mettant un espace en plus entre les deux mots dans mon texte mais bien sur, cela se reproduit plus loin.... donc besoin d'éditer le fichier pas mal de fois. Et quand la description est longue, disons que c'est assez.... long !

Sur le github parser actuel, j'ai trouvé une "issue" où le bug est déjà révélé et une solution donnée : https://github.com/MartinThoma/ics-parser/issues/4
Le fait de commenter la ligne 65 du fichier class.iCalReader.php ne résoud rien, au contraire, cela en rajoute... et changer "trim" par ltrim ou rtrim non plus.
On parle également d'erreurs dans ce même fichier.

Depuis deux jours, j'essaye un autre parser, https://www.a2zwebhelp.com/import-data-from-ics un peu plus récent, mais j'obtiens les mêmes résultats....

Mon texte ne comporte que des balises <p> et </p> ajoutées par l'application du gestionnaire de sport que nous utilisons et le fichier .ics fourni ne comporte aucun autre caractère HTML d'espacement. Donc pas un souci de texte encodé, meme avec du simple Lorem Ipsum copié en texte brut, cela le fait aussi
Pour le mettre en base de données, j'utilise, comme donné dans les parsers, la commande
Code : Sélectionner tout - Visualiser dans une fenêtre à part
$connect->real_escape_string($data['DESCRIPTION'])
pour passer le code HTML dans le champs de la colonne DESCRIPTION.
J'utilise aussi le codage UTF8_bin dans ma base et dans le fichier PHP.


Ici, les mots "Le Comité" ainsi que l'espace après la virgule en fin de texte "rencontrer,je" sont séparés d'un espace puis d'un retour à la ligne, et collés, espace supprimé donc, dans la BDD, ainsi que sur la page bien sur.
tous les fichiers ICS ont ce retour à la ligne après x caractères.
Image

Connaissez-vous d'autres parsers ICS => Mysql/PHP ?
Qui pourrait me solutionner cet énervant souci d'espaces bouffés par les parsers à chaque retour à la ligne du fichier ?

Selon une personne qui m'aide, le fichier n'est pas vraiment conforme a la norme ICS, hors, je n'ai pas accès à la gestion de ce fichier, et les responsables de l'application qui génère ce fichier via un agenda de club estiment que le fichier est correct, cela fonctionne chez eux #-o

J'ai déjà essayé de modifier le code du parser original, avec les solutions données dans le github, ou via l'aide déjà reçue (supprimer les CR / LF et remplacer par des espaces) mais je n'obtiens rien de probant, je dois me gourrer quelque part mais ou ? #-o

Merci de votre aide !

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 9782 Messages

23 juil. 2024, 11:17

Pour savoir si le format fourni respecte la spécification, il faut lire la RFC 2445 et spécifiquement la section 4.1 qui concerne justement les retours à la ligne
https://datatracker.ietf.org/doc/html/r ... ection-4.1
En français ici : http://abcdrfc.free.fr/rfc-vf/rfc2445.html
4.1. Lignes de contenu

L'objet iCalendar est arrangé en lignes de texte individuelles appelées des lignes de contenu (content lines). Les lignes de contenu sont délimitées par des sauts de ligne, c'est-à-dire une séquence CRLF (code décimal 13 US-ASCII suivi du code décimal 10 US-ASCII).

Les lignes de texte NE DEVRAIENT PAS faire plus de 75 octets de long, le saut de ligne exclu. Les longues lignes de contenu DEVRAIENT être découpées en une représentation sur plusieurs lignes à l'aide d'une technique dite de « pliage » (folding) des lignes. C'est-à-dire la coupure d'une longue ligne entre deux caractères en insérant une séquence CRLF suivie immédiatement d'un seul caractère blanc (whitespace) linéaire, à savoir un caratère ESPACE (code décimal 32 US-ASCII) ou TABULATION HORIZONTALE (code décimal 9 US-ASCII). Toute séquence CRLF suivie immédiatement d'un seul caractère blanc linéaire est ignorée (c'est-à-dire supprimée) au traitement du type de contenu.

Par exemple, la ligne suivante :

Code : Tout sélectionner

DESCRIPTION:Voici une longue description sur une seule longue ligne.
Celle-ci peut se représenter par [Note Arthur : j'ai remplacé les espaces par le caractère _ pour bien le rendre visible] :

Code : Tout sélectionner

DESCRIPTION:Voici une lo _ngue description __sur une seule longue ligne.
Le processus consistant à changer cette représentation sur plusieurs lignes pliées en une représentation d'une seule ligne est appelé « dépliage » (unfolding). Le dépliage est réalisé en supprimant la séquence CRLF et le caractère blanc linéaire immédiatement après.

Lors de l'analyse d'une ligne de contenu, les lignes pliées DOIVENT d'abord être dépliées conformément à la procédure décrite précédemment. Lors de la génération d'une ligne de contenu, les lignes plus longues que 75 octets DEVRAIENT être pliées conformément à la procédure de pliage décrite précédemment.
En résumé pour ton exemple "it was decided" s'il y a un retour à la ligne entre as et decided, il doit y avoir :
"it was"+un espace+CRLF+un deuxième espace+"decided"
OU
"it was"CRLF+deux espaces+"decided"

Dans ta capture d'écran on ne peut pas savoir si c'est bien le cas donc à toi de nous dire.
Si tu n'es pas dans l'un des deux cas que j'ai mentionné, alors ton fichier ne respecte pas la norme.

Ma préconisation serait alors que tu fasses un pré-traitement par exemple en remplaçant dans la description tous les CRLF+espace par un espace (alors que selon la spec on devrait les supprimer), puis que tu remplaces tous les double-espaces par un seul espace, et ensuite soit tu tentes de les intégrer comme ça pour voir si ton parser ICS acceptent les lignes >75 caractères.
Soit si ce n'est pas le cas, tu redécoupes en suivant la spec c'est à dire tous les 75 caractères tu ajoutes CRLF+espace
Quand tout le reste a échoué, lisez le mode d'emploi...

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 9782 Messages

24 juil. 2024, 09:16

A noter que les deux librairies que tu cites n'ont pas été mises à jour depuis respectivement 9 et 5 ans, ce qui n'est pas bon signe.

Si tu veux en changer, je te préconise celle-ci qui continue d'être maintenue à jour (et qui est basée sur celle que tu utilises déjà, les évolutions et corrections de bug en +) :
https://github.com/u01jmg3/ics-parser
Quand tout le reste a échoué, lisez le mode d'emploi...