Introduction


Dans une précédente note technique, nous avons présenté la notion de syndication en particulier sous la forme de flux RSS. Nous avons également réalisé un lecteur 4D de flux RSS. Pour compléter, cette présentation, nous allons dans cette nouvelle note nous intéresser à l'aspect serveur de flux RSS depuis une application 4D.

Elaboration de l'exemple

Conception technique

Un flux RSS est une structure XML respectant un modèle particulier.

Pour générer un flux, nous devons donc :
   · choisir un moyen de générer du XML ;
   · choisir le modèle de flux que nous allons respecter.

Pour les différents moyens de générer des structures XML depuis une application 4D, nous vous renvoyons aux notes techniques parues sur ce sujet :
   · Générer du XML avec 4D 2004 - 1ère partie (réf 4D-200409-27-FR)
   · Générer du XML avec 4D 2004 - 2ème partie (réf 4D-200410-28-FR)

Comme le flux RSS doit être servi par le serveur http interne de 4D, nous effectuons le choix de travailler avec des modèles semi-dynamiques. Cette approche évite de coder la génération de l'arbre XML, mais présente l'inconvénient de se limiter à un codage de caractères en ISO-8859-1 (ISO-Latin-1).

Nous avons vu dans la note précédente que deux branches de format RSS co-existaient. La version 2.0 présentant l'avantage d'une plus grande simplicité, nous l'avons retenue pour cet exemple.

Choix des informations à publier

Via le mécanisme de l'élément <link> pour une ressource en ligne ou de l'élément <enclosure> pour le contenu multimedia, nous sommes en mesure de publier tout type d'information géré par une base 4D. Comme il s'agit d'une note technique, nous avons simplement choisi de publier un flux RSS listant les dernières notes techniques parues.

Pour cela, nous avons complété l'application 4DKnowledge_184 en 4D version 2004.

Structure de données

Voici un extrait de la structure de données de la base avec les tables qui vont nous concerner :

Image non disponible

La table [TECHNOTES] contient les méta-données sur les notes techniques, nous retiendrons les champs :

   · [TECHNOTES]Title : le titre de la note

   · [TECHNOTES]Ref4D : la référence de la note

   · [TECHNOTES]Summary : le résumé de la note

   · [TECHNOTES]ID : l'identifiant unique.


La publication s'effectuera sur les 20 dernières notes techniques parues.

Le contenu de la note s'obtient par relation vers la table [ZONESWRITE]. Plusieurs enregistrements peuvent correspondre à un enregistrement [TECHNOTES]. Pour simplifier, nous ne considérerons que le premier enregistrement lié. La note technique au format 4D Write est contenue dans le champ [ZONESWRITE]ZoneNT. 4D Write nous permettra une conversion aisée en HTML.

Pour récupérer les auteurs (plusieurs auteurs peuvent avoir collaborer sur une note), l'application utilise la méthode BuildAuthorsNames et concatène les noms d'auteurs dans la variable interprocess <>NomAuteurs. Il nous suffit de recopier cette méthode en utilisant cette fois une variable process pour obtenir notre liste d'auteurs et garantir un fonctionnement multi-process correct.

Modèle de flux XML semi-dynamique

La première étape de notre publication consiste à créer un modèle semi-dynamique qui, traité par le serveur http, générera automatiquement notre flux XML-RSS.

Voici le code source de ce modèle :

 
Sélectionnez

<?xml version="1.0" encoding="ISO-8859-1"?>
<rss version="2.0">
<channel> 
<title>4D 2004 exemple de publication RSS</title>
<link>http://<!--#4DVAR rss_vt_local_IP-->/4DAction/rss_Home</link>
<language>fr</language>
<managingEditor><!--#4dvar rss_vt_author--></managingEditor>
<description>Exemple de publication RSS avec 4D 2004</description>
<pubDate><!--#4dvar rss_vt_pubDate--></pubDate>
<generator>4eme Dimension 2004</generator>
<docs>http://blogs.law.harvard.edu/tech/rss</docs>
<image>
<title>4D 2004 exemple de publication RSS</title>
<link>http://<!--#4DVAR rss_vt_local_IP-->/4DAction/RSS_Home</link>
<url>http://<!--#4DVAR rss_vt_local_IP-->/images/4dlogo.gif</url>
</image>

<!--#4dloop [TECHNOTES]-->
	<!--#4dscript/rss_BuildAuthorsNames/-->
<item>
<pubDate><!--#4dscript/rss_getPubDate/--></pubDate>
<author><!--#4dvar rss_vt_Author--></author>
<title><!--#4dvar [TECHNOTES]Title-->/<!--#4dvar [TECHNOTES]Ref4D-->/<!--#4dvar rss_vt_NomAuteurs--></title>
<description><!--#4dvar [TECHNOTES]Summary--></description>
<link>http://<!--#4DVAR rss_vt_local_IP-->/4DAction/rss_nt_html/id=<!--#4dvar [TECHNOTES]ID--></link>
<guid>http://<!--#4DVAR rss_vt_local_IP-->/4DAction/rss_nt_html/id=<!--#4dvar [TECHNOTES]ID--></guid>
</item>
<!--#4dendloop-->

</channel>
</rss>

Pour en comprendre le fonctionnement, il faut distinguer deux parties :
1) les méta-données sur le <channel>, constituées par tous les premiers enfants de <channel> jusqu'à </image>
2) la liste des items publiés, un item par note technique. Notre modèle décrit seulement un item encadré par une boucle 4D :

<!--#4dloop [TECHNOTES]--> Structure d'un item <!--#4dendloop-->

Le code compris entre ces deux balises sera répété autant de fois que nous aurons d'enregistrements dans notre sélection [TECHNOTES].

Pour connaître la signification des différents champs de channel, se reporter au lien déjà mentionné dans la note précédente :
http://www.stervinou.com/projets/rss/#sampleFiles.

Notons simplement que nous devrons gérer l'appel décrit dans <link> afin d'afficher le site Web HTML correspondant au <channel> :

<link>http://<!--#4DVAR rss_vt_local_IP-->/4DAction/rss_Home</link>

La variable rss_vt_local_IP contient l'adresse IP du serveur de flux RSS.

Dans la structure <item>, nous ne pouvons écrire le nom des auteurs dans l'enfant <author>. En effet, ce champ doit contenir une adresse email. C'est pourquoi, nous y insérons la variable rss_vt_Author qui contient l'adresse email de la personne responsable des notes techniques chez 4D.

Utilisation de l'élément <enclosure>

Rappelons que l'élément <item> peut également comprendre un enfant facultatif <enclosure>.

Voici ce que nous indique la page citée plus haut :

<enclosure> est un sous-élément facultatif de <item>.

Il possède trois attributs obligatoires :
   · url dit où l'enclosure est située,
   · length dit quelle taille elle fait en octets,
   · type dit quel est son type, un standard type MIME.
L'url doit être une url http.

<enclosure url="http://www.scripting.com/mp3s/weatherReportSuite.mp3" length="12216320" type="audio/mpeg" />

L'exemple indiqué permet de retrouver une ressource mp3, mais il est possible de pointer sur un autre type de fichier, par exemple un BLOB exporté depuis 4D. Par ce mécanisme, il serait possible de proposer au téléchargement les bases exemples accompagnant la note technique. Une autre possibilité serait de proposer une version PDF de la note.

Méthode appelée : rss_serverPublish

Le lecteur appelle la méthode rss_serverPublish grâce à la balise 4DACTION.

Voici son code source :

code 4D
Sélectionnez

` Methode : rss_serverPublish
  ` Description :
  ` routine appelée par un lecteur de flux RSS, renvoi le flux RSS	
  `127.0.0.1/4dAction/rss_ServerPublish/news.rss
  ` 
  ` Parametres :
  ` $1:TEXTE:parametre
  ` 
  ` Version : 1 
  ` Appel : rss_serverPublish(parametre) 
  ` ---------------------------------------------------- 
C_TEXTE($1)

Si ($1="/news.rss")
	
	  `on renvoie les 20 dernières NT
	TOUT SELECTIONNER([TECHNOTES])
	TRIER([TECHNOTES];[TECHNOTES]Date;<)
	REDUIRE SELECTION([TECHNOTES];20)
	Si (Indefinie(<>rss_vt_locaIP))
		rss_surOuverture 
	Sinon 
		Si (<>rss_vt_locaIP="")
			rss_surOuverture 
		Fin de si 
	Fin de si 
C_TEXTE(rss_vt_local_IP)
	rss_vt_local_IP:=<>rss_vt_locaIP
	
	  `date de publication
	C_TEXTE(rss_vt_pubDate)
	C_HEURE($tiTime)
	$tiTime:=Heure courante
	C_DATE($sgmtDate)
	C_HEURE($sgmtTime)
	rss_vt_pubDate:=AP Timestamp to GMT (Date du jour;$tiTime;$sgmtDate;$sgmtTime)
	
	C_TEXTE(rss_vt_author)
	rss_vt_author:="martine.mourier@4D.fr"
	
	Si (Faux)
		ENVOYER FICHIER HTML("rss_nt.xml")
	Sinon   `on passe par un BLOB pour pouvoir effectuer des traitements supplémentaires
		
		C_TEXTE($_vt_rssModel)
		$_vt_rssModel:=rss_get_DossierWeb +"rss_nt.xml"
		
		C_BLOB($_vx_blobRSS)
		DOCUMENT VERS BLOB($_vt_rssModel;$_vx_blobRSS)
		TRAITER BALISES HTML($_vx_blobRSS;$_vx_blobRSS)
		
		  `les résumés contiennent des caractères qui posent problème, on les remplace avant l'envoi
		C_BLOB($_vx_blobReplace)
		TEXTE VERS BLOB("&apos;";$_vx_blobReplace;Texte sans longueur )
		ZBLOB_ReplaceTag (->$_vx_blobRSS;"&#146;";->$_vx_blobReplace)
		
		ENVOYER BLOB HTML($_vx_blobRSS;"text/xml")
	Fin de si 
	
Fin de si

La routine rss_surOuverture se charge de différentes initialisations, dont l'adresse IP du serveur.
Dans une première version, nous avions tenté d'envoyer simplement le modèle xml : ENVOYER FICHIER HTML("rss_nt.xml"), ce qui a pour effet de déclencher le traitement par 4D des balises HTML. Mais cela se traduisait par un échec lors de la tentative de validation du flux car les textes contenaient des caractères invalides pour le codage considéré. Il nous a donc fallu passer par un BLOB intermédiaire, effectuer le traitement des balises par la commande TRAITER BALISES HTML, effectuer les remplacements dans le BLOB, puis envoyer le BLOB final.

Résultat

Voici un extrait du flux XML résultant :

Image non disponible

Affichage dans un lecteur de flux

Image non disponible
Affichage dans Vienna sur MacOSX

Vienna est un agrégateur de syndication compatible RSS et Atom.
Il s'agit d'un projet opensource pour MacOSX, vous pouvez le trouver ici :
http://www.opencommunity.co.uk/vienna2.php

Validation du flux

Nous avions vu qu'il existait des sites de validation de flux RSS, nous avons donc soumis le résultat produit à http://validator.w3.org/ :

Image non disponible
Le flux RSS généré est valide

Lien vers la note complète

La balise <link>, enfant d'item, contient un lien qui doit déclencher l'affichage de la note technique correspondante sous forme d'une page HTML :

<link>http://192.168.1.10/4DAction/rss_nt_html/id=334</link>

Pour ce faire nous appelons la méthode rss_nt_html en lui passant en paramètre l'id de note.

code 4D
Sélectionnez

 ` Methode : rss_nt_html
  ` Description :
  ` envoie la note technique sous forme HTML
  ` 
  ` Parametres :
  ` $1:TEXTE:/id=id NT
  ` 
  ` Version : 1 
  ` Appel : rss_nt_html("/id=id NT") 
  ` ---------------------------------------------------- 

C_TEXTE($1)  `rss_nt_html/id=329

Si ($1#"/images@")  `demande de la page elle-même
	C_ENTIER LONG($_vl_idNT)
	$_vl_idNT:=Num(Sous chaine($1;Position("id=";$1)+Longueur("id=")))
	LECTURE SEULEMENT([ZONESWRITE])
	CHERCHER([ZONESWRITE];[ZONESWRITE]Technote_ID=$_vl_idNT)
	Si (Enregistrements trouves([ZONESWRITE])>0)
		Si (Vrai)  `l'enregistrement du BLOB write au format HTML
			C_TEXTE($_vt_htmlPath)
			$_vt_htmlPath:=Dossier 4D+"NT"+FILE_PlateformSeparator 
			Si (Tester chemin acces($_vt_htmlPath)#Est un répertoire )
				CREER DOSSIER($_vt_htmlPath)
			Fin de si 
			$_vt_htmlPath:=$_vt_htmlPath+"nt"+Chaine($_vl_idNT)+"_"
                    +Chaine(Nombre de millisecondes)+".html"
			C_ENTIER LONG($_vl_refZone)
			$_vl_refZone:=WR Hors ecran 
			WR BLOB VERS ZONE ($_vl_refZone;[ZONESWRITE]ZoneNT)
			WR SAUVER DOCUMENT ($_vl_refZone;$_vt_htmlPath;"HTML")
			WR DETRUIRE HORS ECRAN ($_vl_refZone)
		Fin de si 
		
		ENVOYER FICHIER HTML($_vt_htmlPath)
		
	Fin de si 
	
Sinon   `demande d'une image de la page
	  `http://192.168.1.10/4DAction/rss_nt_html/images/nt328_354859749001.jpg
	
	  `envoi d'une image de lpage HTML
	C_BLOB($_vx_blob)
	C_TEXTE($_vt_htmlPath)
	$_vt_htmlPath:=Dossier 4D+"NT"+FILE_PlateformSeparator +
                          Sous chaine($1;Position("/images/";$1)+1)
	$_vt_htmlPath:=Remplacer chaine($_vt_htmlPath;"/";FILE_PlateformSeparator )
	DOCUMENT VERS BLOB($_vt_htmlPath;$_vx_blob)
	ENVOYER BLOB HTML($_vx_blob;"image/jpeg")
Fin de si

Cette méthode comprend deux cas.
Dans le premier, nous recherchons le premier enregistrement [ZONESWRITE] correspondant à la note technique souhaitée, puis nous effectuons la transformation en HTML. La page correspondante est stockée dans un sous-dossier du dossier 4D :

code 4D
Sélectionnez

$_vt_htmlPath:=Dossier 4D+"NT"+FILE_PlateformSeparator

Ce dossier sera supprimé par un appel à rss_surFermeture lors de la fermeture de l'application.

Lors de la conversion en HTML, 4D Write créé un sous-dossier Images dans lequel il enregistre au format JPEG les images présentes dans la note technique. Ces images sont référencées dans le document HTML sous forme de liens :

http://192.168.1.10/4DAction/rss_nt_html/images/nt328_354859749001.jpg

Le traitement d'un appel de ce type constitue le deuxième cas de notre méthode afin de charger l'image correspondante dans un BLOB, puis de la renvoyer vers le client HTTP.

Nettoyage lors de la fermeture de l'application

Lors de la fermeture de l'application, la méthode base ‘Sur fermeture' appelle rss_surFermeture pour supprimer le dossier contenant nos notes techniques converties en HTML.

Attention, l'utilisation de la commande SUPPRIMER DOSSIER n'est pas suffisante, car elle ne permet de supprimer qu'un dossier vide de contenu !

code 4D
Sélectionnez

  ` Methode : rss_surFermeture
  ` Description :
  ` appelé sur femeture de l'application
  ` pour nettoyer le dossier des pages HTML
  ` 
  ` Parametres :
  ` 
  ` 
  ` Version : 1 
  ` Appel : rss_surFermeture 
  ` ---------------------------------------------------- 

C_TEXTE($_vt_html)
$_vt_html:=Dossier 4D+"NT"+FILE_PlateformSeparator 
Si (Tester chemin acces($_vt_html)=Est un répertoire )
	FILE_DeleteFolder ($_vt_html)
Fin de si

Note :
la méthode FILE_DeleteFolder présentait un bug, il faut donc utiliser la version corrigée présente dans le dossier RSS.

Lien vers le site complet

Le lien <link>, enfant de <channel>, doit nous amener vers le site Web affichant en HTML les informations listées dans le flux RSS  :

<link>http://192.168.1.10/4DAction/rss_Home</link>

Aspect HTML de la liste des notes techniques

Image non disponible

La liste de toutes les notes techniques de la base de données est présentée, triée par date décroissante.

Méthode rss_Home

Nous devons créer une méthode rss_Home appelée par 4DAction et dont voici le source :

code 4D
Sélectionnez

 ` Methode : Méthode : rss_Home
  ` Description :
  ` affichage HTML de toutes les notes techniques de la base
  ` 
  ` Parametres :
  ` $1:TEXTE:vide
  ` 
  ` Version : 1 
  ` Appel : http://192.168.1.10/4DAction/rss_Home
  ` ---------------------------------------------------- 
  
C_TEXTE($1)

Si (Indefinie(<>rss_vt_locaIP))
	rss_surOuverture 
Fin de si 
C_TEXTE(rss_vt_local_IP)
rss_vt_local_IP:=<>rss_vt_locaIP

LECTURE SEULEMENT([TECHNOTES])
TOUT SELECTIONNER([TECHNOTES])
TRIER([TECHNOTES];[TECHNOTES]Date;<)

ENVOYER FICHIER HTML("rss_nt_full.shtm")

Cette méthode, très simple, effectue la sélection des notes techniques, initialise les variables process utilisées par balises 4DVAR et renvoie la page semi-dynamique "rss_nt_full.shtm".

Modèle semi-dynamique

Voici le modèle semi-dynamique utilisé :

 
Sélectionnez

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Liste des notes techniques</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>

<body>
<h1 align="center"><img src="/images/4D_Rss.gif" width="39" height="53"><strong> 
  Liste des notes techniques </strong></h1> 
  
  <!--#4dloop [TECHNOTES]-->
		<!--#4dscript/rss_BuildAuthorsNames/-->
		<Table width="100%" border="0">
		  <tr> 
		    <td width="10%"> <strong>Titre :</strong></td>
		    <td width="60%"><a href="http://<!--#4DVAR rss_vt_local_IP-->/4DAction/rss_nt_html/id=<!--#4dvar [TECHNOTES]ID-->"><!--#4dvar [TECHNOTES]Title--></a></td>
		    <td width="10%"><div align="right"><strong>Ref4D :</strong></div></td>
		    <td width="20%"> <!--#4dvar [TECHNOTES]Ref4D--> </td>
		  </tr>
		  <tr> 
		    <td><strong>Date :</strong></td>
		    <td> <!--#4dvar [TECHNOTES]Date--> </td>
		    <td><div align="right"><strong>Auteurs :</strong></div></td>
		    <td><!--#4DVAR rss_vt_NomAuteurs---></td>
		  </tr>
		</Table>
		<!--#4dvar [TECHNOTES]Summary-->
		<hr>
	<!--#4dendloop-->

	<br>
</body>
</html>

Rien de particulier non plus dans cette page semi-dynamique classique dont l'analyse et le traitement seront effectués automatiquement par le serveur http de 4D.

Installation dans 4D Knowledge.4DB

Recopie des éléments requis

Aucun formulaire n'est utilisé.

Il suffit :

· de transférer via 4D Insider les méthodes du dossier RSS de la librairie rss.4IL dans votre version de 4D Knowledge.4DB ;

Image non disponible

· de recopier le dossier "DossierWeb" auprès de "4D Knowledge.4DB" ;

Image non disponible
Contenu de DossierWeb

· puis d'effectuer les vérifications décrites au paragraphe suivant.

Paramétrage du serveur http

Pour que tout cela fonctionne, il faut que le serveur http et les méthodes utilisées soient paramétrées convenablement.

Méthodes accédées par le serveur http

Rappelons que toutes les méthodes sollicitées par le serveur http doivent, en version 2004, être paramétrées explicitement en cochant "Disponible via 4DACTION, 4DMETHOD et 4DSCRIPT" dans leurs propriétés :

Image non disponible

Ces méthodes sont ensuite reconnaissables à leur icône particulière dans l'explorateur :

Image non disponible

DossierWeb

Dans la version originale de l'application, la racine HTML par défaut se nommait "WebFolder", remplaçons-la par "DossierWeb" pour compatibilité avec nos méthodes.

Image non disponible

Vérification dans un client riche

La société Adobe propose un outil de création de client riche Internet : Flex.

Cet environnement permet de réaliser des applications aux interfaces évoluées s'exécutant dans le contexte d'un navigateur grâce au plugin Flash player dans sa version 9 :
www.adobe.com/fr/products/flex/

Il est très simple avec cet outil de créer un lecteur de flux RSS qui affiche les données publiées par notre application. Si vous travaillez en local, il vous suffit de saisir l'URL suivante dans le navigateur pour voir un exemple :
http://127.0.0.1/BlogReader.html

Et le client riche affiche le flux RSS :

Image non disponible

Conclusion

Dans cette deuxième note sur les flux RSS, nous avons montré comment publier un flux depuis une application 4D existante. Vous pouvez ainsi constater qu'il s'agit d'une opération technique assez simple. Dans les mois qui suivent, nous devrions donc assister à une forte augmentation des publications RSS depuis des applications 4D !

Image non disponible

Télécharger la base exemple


Télécharger la base exemple.