Affichage des articles dont le libellé est Appinventor. Afficher tous les articles
Affichage des articles dont le libellé est Appinventor. Afficher tous les articles

15/03/2016

Rdf Facile - Afficher les informations récupérées sur AppInventor

[ cet article fait partie de la série RDF FACILE - Mon petit BigData ]

Bien dans les articles précédents, nous avons : 
- mis en place un serveur RDF / Fuseki, qui nous fournit un accès à un endpoint pour effectuer des requêtes Sparql.
- développé une application sous AppInventor pour effectuer une requête sur cet endpoint.
- modifié cette application pour ajouter des informations sur ce serveur

Nous allons maintenant reprendre cette application pour formater différemment les informations qui nous sont retournées,

On va repartir de la dernière version, celle qui permet d'ajouter des informations. On peut la récupérer ici : http://ai2.appinventor.mit.edu/?galleryId=5233374557372416

Dans la version précédente, on avait juste affiché le résultat de la requete dans la zone de texte (entre les deux version, j'avais même inséré une page pour mieux les visualiser), mais ce n'est pas ce que nous voulons, c'est illisible... on va donc reformater le résultat de la requete.

Le résultat qui nous est retourné est au format JSON et ressemble à ça :

{
  "head": {
    "vars": [ "s" , "p" , "o" ]
  } ,
  "results": {
    "bindings": [
      {
        "s": { "type": "uri" , "value": "http://example.org/dog1" } ,
        "p": { "type": "uri" , "value": "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" } ,
        "o": { "type": "uri" , "value": "http://example.org/animal" }
      } ,
      {
        "s": { "type": "uri" , "value": "http://example.org/cat1" } ,
        "p": { "type": "uri" , "value": "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" } ,
        "o": { "type": "uri" , "value": "http://example.org/cat" }
      } ,
      {
        "s": { "type": "uri" , "value": "http://example.org/cat" } ,
        "p": { "type": "uri" , "value": "http://www.w3.org/2000/01/rdf-schema#subClassOf" } ,
        "o": { "type": "uri" , "value": "http://example.org/animal" }
      } ,
      {
        "s": { "type": "uri" , "value": "http://example.org/zoo/host" } ,
        "p": { "type": "uri" , "value": "http://www.w3.org/2000/01/rdf-schema#range" } ,
        "o": { "type": "uri" , "value": "http://example.org/animal" }
      } ,
      {
        "s": { "type": "uri" , "value": "http://example.org/zoo1" } ,
        "p": { "type": "uri" , "value": "http://example.org/zoo/host" } ,
        "o": { "type": "uri" , "value": "http://example.org/cat2" }
      } ,
     ...
      {
        "s": { "type": "uri" , "value": "http://example.org/LucileP" } ,
        "p": { "type": "uri" , "value": "http://example.org/participe" } ,
        "o": { "type": "uri" , "value": "http://example.org/AperoboLyon" }
      }
    ]
  }
}


L'objectif étant de récupérer tous les triplets, comme celui-la : 
      {
        "s": { "type": "uri" , "value": "http://example.org/dog1" } ,
        "p": { "type": "uri" , "value": "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" } ,
        "o": { "type": "uri" , "value": "http://example.org/animal" }
      } 

c'est à dire qu'on va prendre tout ce qui se trouve après '"bindings": [' et jusqu'à ']'


Pour mieux visualiser, on va modifier la requête et limiter le nombre de résultat à 3, notre variable "requeteTest" sera donc :
http://rdf-smag0.rhcloud.com/ds/query?query=SELECT+*+WHERE+%7B%3Fs+%3Fp+%3Fo+%7D%0D%0ALIMIT+3&output=json

et on va exporter le travail de formatage dans une fonction que l'on va appeler "formateTexte":
--> créer la fonction "formateTexte", la variable "resultat", et modifiez la fonction "When Web1.GotText" comme ceci :



-> Web1.GotText envoie "responseContent" à "formateTexte" dans la variable "texteAFormater"
-> Pour comprendre la fonction "formateTexte", commencez par la droite :
-> On récupère "texteAFormater", on le split/coupe à "bindings": [, on récupère le 2 ème élément de la liste créée par le split, on resplit à ] , on récupère le premier élément, et on envoie ça dans résultat, on affiche résultat dans TextBox1.

Si vous avez bien modifié la requête pour limiter le nombre de résultat à 3, le texte qui devrait maintenant s'afficher dans TextBox1 est celui-ci (revenez sur la page d'accueil et rouvrez l'écran "Visualisation" pour rafraichir, puisque la requete s'execute à l'initialisation de l'écran ou vous pouvez ajouter un bouton qui reprend le code de "When Visualisation.Initialise" pour actualiser plus vite) :  (Avec le formatage en moins )

 {
        "s": { "type": "uri" , "value": "http://example.org/dog1" } ,
        "p": { "type": "uri" , "value": "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" } ,
        "o": { "type": "uri" , "value": "http://example.org/animal" }
      } ,
      {
        "s": { "type": "uri" , "value": "http://example.org/cat1" } ,
        "p": { "type": "uri" , "value": "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" } ,
        "o": { "type": "uri" , "value": "http://example.org/cat" }
      } ,
      {
        "s": { "type": "uri" , "value": "http://example.org/cat" } ,
        "p": { "type": "uri" , "value": "http://www.w3.org/2000/01/rdf-schema#subClassOf" } ,
        "o": { "type": "uri" , "value": "http://example.org/animal" }
      }

Bien bien bien,
D'abord, on "trim" pour enlever les espaces au début et à la fin, et on va continuer à spliter...
L'élement qui séparent nos triplet, maintenant c'est  '} , {'
mais avec un retour à la ligne (ça fait deux heures que je suis dessus !!! mais ça passe ! )
en fait, le séparateur c'est "je ferme l'acolade, je mets un espace, une virgule, le retour à la ligne formalisé par "\n", ensuite, on a six espaces, en une accolade qui ouvre, ça donne : } ,\n {


Pour voir vraiment ce que ça donne, et où on en est, on va remplacer notre TextBox1 et  afficher nos resultats dans un gestionnaire de liste... là, vous pouvez utilisez celui que vous voulez  :
ListPicker, Spinner, ListView... ça dépend de votre besoin, ou de ce que vous souhaitez faire ensuite...
Pour la démo, j'ai mis les trois, et voilà ce que ça nous donne dans le "Designer" et le code modifié depuis la dernière image (avec le bouton actualise ) :


Et la partie code : 



Le resultat est récupérable ici : http://ai2.appinventor.mit.edu/?galleryId=4834449967022080


Evidemment, on va encore splitter pour avoir l'affichage voulu... et surtout choisir entre ListPicker, Spinner et Listview...
Bon en fait, j'hésite entre ListPicker & Listview, on verra plus tard, ... Hop ! out Spinner...

De plus, on va se refaire une petite fonction pour formater les différents élements de la List comme on le souhaite...
Un petit "Layout Horizontal" mettre notre bouton actualise à côté de "Retour Accueil " (optionnel, mais ça laisse plus de place pour le reste.

Commençons par sortir notre liste en l'envoyant à la fonction "formateItem", et on la renvoie tout de suite dans "listeItem" que l'on affiche dans nos "ListPicker" & "Listview" :


Attention, maintenant, on va spiltter... je ne détaille pas, on split sur le motif du début, on prend le deuxième element, on resplit sur le motif de fin, et on prend le premier élement, et ça pour avoir les trois elements de notre triplet : (Sujet, propriete, Objet )


On a maintenant chaque Item de la liste qui ressemble à un truc comme ça :
 "type": "uri" , "value": "http://example.org/dog1"
 "type": "uri" , "value": "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
 "type": "uri" , "value": "http://example.org/animal"

un dernier Split pour récupérer seulement les valeurs  :



Après, on peut encore travailler sur les prefix, mais c'est déjà pas mal pour aujourd'hui...
Pour plus de fun, je repasse la limite des résultats à 100, et je vous mets le bouzin ici :
http://ai2.appinventor.mit.edu/?galleryId=4919353954271232

[ cet article fait partie de la série RDF FACILE - Mon petit BigData ]



13/03/2016

big data facile - une application pour insérer des données sur un serveur Fuseki

[ cet article fait partie de la série RDF FACILE - Mon petit BigData ]

Repartons de l'application Android faite avec AppInventor pour visualiser les informations de notre serveur Fuseki comme nous l'avons construite ici : http://smag0.blogspot.fr/2016/03/bigdata-facile-une-application-android.html

Si vous avez tout bien suivi, vous avez créé un écran "Saisie", et nous avons sur cette page http://smag0.blogspot.fr/2016/03/un-serveur-fuseki-rdf-bigdata-sur.html  une piste pour construire la requete que nous devons envoyer pour insérer des données :

PREFIX rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs:   <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex:   <http://example.org/>
PREFIX zoo:   <http://example.org/zoo/>
PREFIX owl: <http://www.w3.org/2002/07/owl#>


INSERT DATA {
GRAPH <http://example/bookStore>
{
ex:dog1    rdf:type         ex:animal .
ex:cat1    rdf:type         ex:cat .
ex:cat     rdfs:subClassOf  ex:animal .
zoo:host   rdfs:range       ex:animal .
ex:zoo1    zoo:host         ex:cat2 .
ex:cat3    owl:sameAs       ex:cat2 .
}
}

Je rappelle que pour les flémards, le code de la première partie (récupération des données) est accessible ici : http://ai2.appinventor.mit.edu/?galleryId=4993525195735040

Les données au format RDF se présentent sous la forme de triplets, si c'est pas clair pour toi, jette un oeil là https://fr.wikipedia.org/wiki/Resource_Description_Framework .
Nous avons donc besoin de trois champs.
Dans App Inventor, passez sur l'écran "Saisie" que nous avons créé dans le tuto précédent, et insérez trois zone de texte ( on va repasser en english, car la traduction en français pose quelques problèmes lors des tests...)
Comme pour la page "Visualisation", insérons un bouton retour accueil, avec le même code que précedemment.
Ainsi que trois zones de texte, profitez-en pour les renommer, passer leur "width" à "Fill Parent" et mettre des Hint selon le contenu que l'on attend : Sujet, propriete, Objet... ça sera plus parlant pour la suite.
Oui , je sais , Sujet et Objet ont droit à la majuscule, mais pas "propriété", c'est un peu comme ça en RDF... alors gardons cette norme, ça ne peut pas faire de mal...
N'oubliez pas aussi d'ajouter un composant Web1 que vous trouverez dans Connectivity, c'est lui qui va nous faire la requête POST, mais pour ça, il va falloir lui donner la bonne requête.
Complétez par une nouvelle zone de texte, que l'on nommera "Résultat", avec Height et Width à "Fill Parent, et "Hint" à "Attente resultat".



Passons maintenant à l'envers du décor, en cliquant sur le bouton "Blocks".
Pour faire au plus simple, considérons que les trois éléments que nous allons insérer avec notre première requête, ont tous le même préfixe :  PREFIX ex:   <http://example.org/>.

Notre application devra donc envoyer la requete :

PREFIX ex:   <http://example.org/>

INSERT DATA {
GRAPH <http://example/bookStore>
{
ex:Sujet    ex:propriete         ex:Objet .
}
}

Et pour ce faire, nous aurons besoin de récupérer les valeurs qui se trouvent dans nos trois zones de texte.

Commençons par la ligne où se trouve notre triplet (ex:Sujet    ex:propriete         ex:Objet .)
Les quelques blocs suivants devraient nous faire apparaître notre ligne dans la zone de texte "Résultat" :
On initialise nos variables Sujet, propriete, Objet, ainsi que la requeteUpdate.
Au click du bouton, on concatène la chaîne "ex:" avec chacune des valeurs récupérées dans nos trois textBox.
On construit ensuite notre requeteUpdate, en joignant nos trois variables, en les séparant d'un espace .
Astuce : pour ajouter une nouvelle ligne dans un "join", cliquez sur la roue sur fond bleu.
Attention, bien mettre un espace dans les deux blocs entre "get  global Sujet " et "get global propriete" ainsi que entre les blocs "get global propriete" et "get global Objet" .
On termine notre "set global requeteUpdate" par un bloc texte qui contient un espace et un point " .", c'est ainsi qu'on termine un triplet simple en rdf.
Et pour finir, on affiche notre "global requeteUpdate" dans la zone texte "Resultat"



Pour tester, utilisez l'appli " compagnon App Inventor", et entrez un triplet rdf, par exemple :
dans Sujet : David
dans propriété : type
et dans Objet : Personne
cliquez ensuite sur "Envoyer"

Si tout se passe bien, vous devriez immédiatement voir apparaître :
ex:David ex:type ex:Personne . 
Si c'est le cas, BRAVO ! on y est presque, il suffit juste d'envoyer tout ça au serveur (http://rdf-smag0.rhcloud.com/) mais avant de pouvoir lui demander d'intégrer ces information, nous devons y mettre les formes...

L'enrobage sauvage...
Pour voir si ça marche, on va juste englober notre triplet par le strict nécessaire :
Avant notre triplet, on va mettre :
PREFIX ex:   <http://example.org/>
INSERT DATA {
GRAPH <http://example/bookStore>
{
et à près, on fermera par
}
}

C'est pas très orthodoxe, mais le principal, c'est de tester si ça marche, alors on va la faire simple, on aura tout le loisir de faire joli ensuite.
Attention.... POF :
-  une variable "debutRequete" avec comme valeur :
PREFIX ex:   <http://example.org/> INSERT DATA { GRAPH <http://example/bookStore> 
- et une variable "finRequete" avec comme valeur :
}}

Bouhhh ! c'est pas bien !!!



On complète ensuite notre "requeteUpdate", en ajoutant deux blocs :
 "get global debutRequete" (avant "get global Sujet" )
et "get global finRequete" (après le bloc " .").

Votre code devrait maintenant ressembler à ceci :


et le texte qui s'affiche dans la zone de texte "Resultat" à ceci :
PREFIX ex:   <http://example.org/> INSERT DATA { GRAPH <http://example/bookStore> ex:David ex:type ex:Personne . }}


Nous avons maintenant nos données, que nous avons mis dans une enveloppe.
Le destinataire, c'est le serveur http://rdf-smag0.rhcloud.com/, on va même être plus précis, car sa boite au lettre se trouve à l'adresse : http://rdf-smag0.rhcloud.com/update, et il va falloir envoyer à cette adresse, une requête de type POST.
Il ne reste plus qu'à mettre en place le transporteur... et c'est là qu'intervient notre composant "WEB1" que nous avions inséré au tout début de ce post...

Créons maintenant une nouvelle variable que nous nommerons "endpointUpdate" et donnons-lui la valeur de l'adresse de la boite aux lettres de notre serveur "http://rdf-smag0.rhcloud.com/ds/update"

Ensuite, on sort le bloc "set Resultat.Text" du bloc "When EnvoyerBouton.click", et à la place, on y met deux blocs : "set Web1.Url" et "Call Web1.PostText" qui vont respectivement donner à WEB1 l'adresse de destination, et la valeur du paramètre "update=".

Et bien voilà, le plus dur est fait... pas insurmontable, quand même...
juste une toute petite dernière chose, pour être sûr du résultat...
Ajouter un bloc "When Web1.gotText" qui s'exécutera dès que la réponse du serveur arrivera... avec à l'intérieur, l'affichage dans la zone de texte "Résultat", de la valeur "reponseContent".



Lorsque vous testez maintenant votre appli, ( MIT compagnon) et que vous cliquez sur "Envoyer", vous devriez voir apparaitre dans la zone "Résultat", la ligne suivante :
<html><head></head><body><h1>Success</h1><p>Update succeeded </p></body></html>


et c'est plutôt bon signe : <h1>Success</h1><p>Update succeeded </p>

Pour vérifier, repassez sur l'écran d'accueil après avoir ajouté le code du bouton "retour Accueil", puis sur l'écran "Visualisation" comme nous l'avons implémenté ici http://smag0.blogspot.fr/2016/03/bigdata-facile-une-application-android.html
mais c'est plus joli ici http://rdf-smag0.rhcloud.com/ds/query?query=select+*+where+%7B%3Fs+%3Fp+%3Fo%7D&output=text , car pour l'instant dans la visualisation, on n'a pas formaté le résultat...


Si t'es arrivé jusque là, t'es plus un flemmard, alors cadeau : le code sur AppInventor : http://ai2.appinventor.mit.edu/?galleryId=5233374557372416

Les retours sont les bienvenus, si j'ai fait des boulettes, ou si je ne suis pas clair. Pour rappel : ceux qui veulent s'installer leur propre serveur peuvent le faire en local (en téléchargeant Apache Fuseki ou sur le cloud , par exemple Openshift en récupérant le source ici : https://github.com/scenaristeur/smag0-fuseki-rdf-openshift



[ cet article fait partie de la série RDF FACILE - Mon petit BigData ]



01/10/2014

Android , Fuseki & RDF. Utilisation de APPINVENTOR 2 pour envoyer des triplets au serveur Fuseki

Pour rappel :
Le but est de faciliter l'échange d'information entre les différents objets connectés.
On utilise un serveur Fuseki. Le serveur fuseki permet de stocker les informations sous forme de triplets  Sujet/propriété/Objet comme par exemple  ("Voiture" "couleur" "rouge")
voir RDF / web sémantique / Jena / Fuseki ... pour plus d'infos sur le sujet.

pour résumer : RDF permet aux machines d'inférer ou de déduire des informations qui n'existent pas , à partir des relations entre les informations qui existent.

Dans le cadre du projet, nous avons besoin d'un serveur où sont partagées les informations.
Attention, les données ne sont pour l'instant pas sécurisées et tout le monde peut y mettre / remplacer, effacer tout et n'importe quoi.
Ce serveur est un peu un tableau blanc où chacun peut poser tout type d'information.

Le serveur est accessible via l'adresse : http://fuseki-smag0.rhcloud.com

pour consulter les informations qui y sont présentes, vous pouvez utiliser :
-  les formulaires en cliquant sur "Control Panel", choisissez le dataset "ds" puis cliquez sur "Select".
ensuite dans la zone de texte "Sparql Query" saisissez la requete suivante :

select * WHERE { ?s ?p ?o} LIMIT 100

puis dans Output, choisissez "xml"
cliquez ensuite sur "Get Result"

ceci vous affiche  100  informations
On trouve des infos pour faire des requetes sparql un peu partout : exemple là http://rdf.myexperiment.org/howtosparql?page=Using+the+SPARQL+Endpoint#

- ou directement :
http://fuseki-smag0.rhcloud.com/ds/query?query=select+*+WHERE+%7B%3Fs+%3Fp+%3Fo%7D&output=xml&stylesheet=%2Fxml-to-html.xsl


Depuis un bout de temps, je cherche le moyen d'envoyer des informations au format RDF sur ce serveur depuis mon smartphone Android pour pouvoir transmettre des informations au système Smag qui est sensé gérer les objets connectés que nous aurons dans nos habitations.

Plusieurs tests avec APDE, androjena, arqoid, (voir articles précédents...) mais je ne trouve pas ce qu'il faut, car l'utilisation de Jena plante les applis android

Par contre avec Appinventor j'ai un début de solution.
Le serveur Fuseki, n'acceptant que les requetes Post ou Put pour updater les informations, il a fallu décortiquer la requete http :

PREFIX dc: <http://purl.org/dc/elements/1.1/>
 PREFIX ns: <http://example.org/ns#>
 INSERT DATA {
 GRAPH <http://example/bookStore> {
  <http://example/book14>  ns:price  6 }
 }


Pour tester, modifier l'appli, vous devez télécharger ce fichier : https://drive.google.com/file/d/0B0zEK4yLB5C6cTZvN01jemQ5bHM/edit?usp=sharing

et l'importer dans Appinventor : http://ai2.appinventor.mit.edu/

Reste maintenant à récupérer les Prefix, et proposer une liste de propriétés courantes, récupération des infos, recherches dans la base... modification des infos, et vote pour chaque info, pour valider leur véracité, sécurisation des données perso.

un coup de main pour l'utilisation de Appinventor ou de ce fichier ? n'hésitez pas à laisser un message