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 ]



14/03/2016

Projet, idée, problème... partager sous forme de graphe, collaborer... et bien plus encore...

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

Si mes explications ne sont pas claires, y'a toujours Wikipedia : https://fr.wikipedia.org/wiki/Resource_Description_Framework

Parti d'un projet un peu loufoque, il est vrai d'"un robot qui range ma chambre", il m'est très vite apparu que ce projet d'envergure n'était pas simple à partager avec mon entourage, et encore moins avec des inconnus.
Pour ce projet, j'avais imaginé non pas un robot qui rangerait, mais une multitude de robots, d'objets connectés, de modules qui s'entraideraient, collaboreraient.
Ils devaient pour ce faire s'échanger des informations dont la structure devaient être libre de toute modification au cours du temps, et chacun de ces robots aurait la possibilité de compléter, corriger les informations en fonction de ses capacités à capter l'environnement.
Au fil de mes recherches, le format qui me parut le plus adapté fut le RDF et je n'ai rien trouvé de mieux depuis, mais la discussion reste ouverte ;-)
RDF
Le rdf nous permet, en effet, à partir de notions toutes simples que tout le monde peut comprendre, de partager et d'échanger, de décrire tout et n'importe quoi... J'imaginais alors que pour que mes robots puissent comprendre leur environnement, il leur fallait déjà le connaître un petit peu... Mes quelques connaissances sur le Machine Learning en plein boom me laissant supposer que ces différents modules pourraient être dotés d'ici peu d'une quelconque intelligence artificielle répondant aux besoins qui leur seraient demandés : apprentissage, adaptation au contexte, à l'utilisateur...
La première notion essentielle, le triplet, est décrite un peu plus bas, mais avant ça, nous devons parler de l'information...
L'information
Si je vous dis "Voiture", tout le monde ou presque voit à peut près ce que cela représente. Méa Culpa à ceux qui pourraient penser que je les prends pour des ânes, mais les notions que l'ont va aborder ici, même si elles sont simples, imposent d'oublier tout ce que vous savez, ou plutôt de regarder le monde sous un autre angle, avec un peu plus de recul... Et de bien considérer que chacun peut posséder une vision différente de chaque concept, selon son origine, ses habitudes, sa culture...
Si cette fois, je vous dis "La Voiture de David", vous m'accorderez que l'information est plus précise... Dans "La Voiture de David est jaune et c'est une Opel Corsa", on aura encore plus d'informations...

Dans un premier temps, et pour se rapprocher de ce que tout le monde connait, ce que nous allons devoir faire (tant que le Natural Langage Processing n'est pas intégré au site), c'est de découper cette information... c'est un peu comme un tableau à deux lignes, avec dans la première ligne, les champs et dans la deuxième les valeurs.

champ 1 champ 2 champ 3 champ 4 ... ...
Ce que nous voulons décrire valeur 1 valeur 2 valeur 3 valeur 4 ... ...

Par exemple, pour décrire ma voiture, je pourrais utiliser le tableau suivant :
marque modèle couleur vitesse maxi propriétaire position actuelle
Voiture de David Opel Corsa Jaune 128 000 David Lyon

Comme vous avez pu le constater, les propriétés (champs dans le tableau) sont très libres et nous laissent le loisir de décrire tout et n'importe quoi... J'utilise ici le terme "propriété", et ceux qui sont allés voir la page Wikipédia sur le RDF aurons constaté qu'il est mentionné "prédicat"... Et bien les deux sont équivalents... et oui, faudra vous y faire...
Bon allez, je n'y tiens plus... passons au triplet...
Le Triplet
Repartons de l'exemple que nous avons pris précédemment : "La Voiture de David est jaune et c'est une Opel Corsa".
Nous avons découpé les informations de manière atomique dans le tableau à deux lignes... et bien ce tableau que n'importe qui est capable de reproduire, pour décrire n'importe quel concept, objet, procédure..., nous donne tout naturellement les triplets que nous attendions...
Le triplet se matérialise sous la forme de trois éléments :
  • un sujet : c'est la chose que l'on va décrire,
  • un objet : c'est une chose avec laquelle notre sujet est lié,
  • une propriété (ou prédicat) : c'est la nature de la relation entre le sujet et l'objet.

Ainsi notre tableau précédent nous donne les triplets suivants :
(Voiture de David, marque, Opel)
(Voiture de David, modèle, Corsa)
(Voiture de David, couleur, Jaune)
(Voiture de David, vitesse maxi, 128 000) --> enfin seulement dans les bonnes descentes...
(Voiture de David, propriétaire, David)
(Voiture de David, position actuelle, Lyon)
A quoi ça sert ? me direz-vous ? Ouais super... j'ai perdu 10 minutes à lire un truc qui ne sert à rien...
Meuh non, va voir plus bas !
Le Graphe
Bien maintenant que nous avons nos triplets, envoyons-les dans un "graphMaker" tel que http://smag0.meteor.com,

avec quelques exemples de fichiers rdf /ttl /owl (http://smag-smag0.rhcloud.com/dca/ontologies/)


On obtient alors le début d'un graphe : 


Mais les choses deviennent intéressantes lorsque l'on rajoute de nouveaux triplets :

(Voiture de David, type, Voiture)
(David, type, Personne)
(Lyon, type, Ville)
(Voiture, subclassOf, Vehicule)
(David, habite, Lyon)
(Paris, type, Ville)
(Madrid, type, Ville)
(Paris, capitale de, France)
(France, type, Pays)
(Soleil, couleur, Jaune)
(Lyon, sameAs, http://fr.dbpedia.org/page/Lyon)
...
Oulà ! STOP !, c'est quoi cette dernière ligne ??? !!! ce dernier "triplet", comme ils disent ???
Attention ! Là, on rentre dans le vif du sujet
Sur cette dernière ligne (Lyon, sameAs, http://fr.dbpedia.org/page/Lyon), qui et toujours un triplet, y'a un max de nouvelles notions, mais j'imagine que si vous avez tenu jusque là, vous êtes prêt à affronter la suite :
  • sameAs : la propriété "sameAs", comme vous pourrez le constater, si le RDF continue de vous intéresser, nous permet de spécifier que le sujet (Lyon) et l'objet (http://fr.dbpedia.org/page/Lyon) du triplet représentent la même chose.
    Et c'est là, la plus grande qualité du RDF, "it's a kind of magic", c'est là que la magie "s'opère"... C'est là que s'ouvre une infinité de possibilité...
    Vous pouviez déjà grâce au RDF tout décrire, vous pouvez maintenant connecter votre graphe à d'autres graphes, d'autres bases de données RDF crées par d'autres... comme celle de DBPedia, qui reprend les informations contenues dans Wikipedia, et vous les propose au format RDF : allez jeter un œil sur la page en question : http://fr.dbpedia.org/page/Lyon et vous verrez d'autres propriétés apparaître, comme la population, la superficie, les monuments... ainsi que des liens vers d'autres bases de données ou des endpoint sparql
  • http://fr.dbpedia.org/page/Lyon : à décrire...
  • prefix
  • sparql
La suite ?
Bandes d'impatients, commencez par jeter un oeil sur dreamcatcher -> http://dreamcatcher-smag1.rhcloud.com/#!/outils (patientez 30 secondes que le serveur redémarre l'appli)



 vous y trouverez l'aide pour vous balader dans les graphes..., sinon en attendant la suite, vous pouvez également interpeller le fautif, lui posez vos questions, ou faire part de vos attentes, vos idées sur Twitter : @DFaveris
d'autres infos techniques se trouvent sur http://smag0.blogspot.fr

Un bon tendeur...
ça tient bien, tiens, ça tombe bien !

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 ]



bigdata facile - une application Android pour visualiser, les informations sur un serveur bigdata perso

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

Le but de ce post est de faciliter la construction d'une petite appli pour mettre à jour, consulter, visualiser les informations d'un serveur Fuseki (serveur RDF/Sparql), et de créer ainsi, notre petit #bigdata à nous ;-).

La première étape est d'avoir accès à un serveur Fuseki/Sparql. Pour ce faire, vous pouvez suivre les instructions décrites ici : http://smag0.blogspot.fr/2016/03/un-serveur-fuseki-rdf-bigdata-sur.html ou utiliser celui qui y est mentionné ( serveur de test : http://rdf-smag0.rhcloud.com/ )

Pour créer l'appli, on va utiliser ce qu'il y a de plus simple --> Pas la peine de se prendre la tête...


Créez un compte sur App inventor, et commencez un nouveau projet. ( Les flémards peuvent aussi piquer le code ici : http://ai2.appinventor.mit.edu/?galleryId=4993525195735040).

Si vous n'avez jamais pratiqué App Inventor, faites-vous la main avec les tutos, ou posez-vos questions en commentaire de ce post, on trouvera bien quelqu'un pour vous répondre...
Mais d'abord commençons par faire le point sur ce qui va nous être utile :
  1. une requête pour aller interroger le serveur : http://rdf-smag0.rhcloud.com/ds/query?query=select+*+where+%7B%3Fs%3Fp%3Fo%7D&output=json . Je sais, c'est un peu brut pour ceux qui ne connaissent pas le rdf, et les requêtes Sparql, mais ce n'est pas le sujet de cet article...
Entrons dans le vif du sujet
Lorsque vous ouvrez un nouveau projet sur App inventor, le premier écran est Screen1, on va en créer deux autres grâce au bouton "ajouter écran" (en admettant que vous ayez passé votre interface de App Inventor en français... si si, c'est possible, en haut à droite ).
Nos deux nouveaux écrans pourraient par exemple s'appeler "Visualisation" et "Saisie".
Sur l'écran Screen1, créez deux boutons pour accéder aux écrans que l'on vient de créer, et affectez leur le code pour ouvrir les écrans respectifs.
( Pour la bascule Designer / Bloc, utilisez les deux boutons "Designer" & "Blocs", juste au dessus du panneau "Propriétés" )




Avec les blocs : 




Attaquons-nous pour commencer à l'écran "Visualisation".
Pour voir ce que notre serveur a dans le ventre, on va ajouter un composant "WEB", on le trouve dans "Connectivité" de la "Palette". C'est lui qui se chargera de la requete.
Ajoutez aussi un bouton pour le retour sur l'écran d'accueil,  une "zone de texte" avec les propriétés Height et Width en "remplir parent", et "Nuance" en "Attente résultat", c'est là que l'on affichera le retour de la requête, dans un premier temps.


Et en backstage : 



Dans le mode "Blocs", Ajouter une variable , nommez-la "requeteTest" et donnez-lui la valeur : http://rdf-smag0.rhcloud.com/ds/query?query=select+*+where+%7B%3Fs%3Fp%3Fo%7D&output=json 
Complétez les blocs de codes comme l'image ci dessus : 

Quand "Visualisation initialise, faire " / mettre Web1.Url à obtenir global requestTest, appeler Web1.Obtenir

Quand Web1.Texte reçu, faire / Mettre TextBox1.Texte à / obtenir Contenu de réponse

et le code pour le retour sur la page d'accueil : 

Quand Bouton1Click, faire / Fermer l'écran

Vous pouvez déjà tester votre appli , le mieux , c'est avec le AI Compagnon, dans le menu "Connecté", mais c'est pas encore au point, repassez sur l'interface en anglais, orsque vous souhaitez tester votre application --> attention, verifiez que "contenu de réponse s'est bien traduit en "Content réponse" .

Si tout va bien, vous devriez voir appraitre dans la zone de texte, un truc qui ressemble à : 



{
  "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/cat3" } ,
        "p": { "type": "uri" , "value": "http://www.w3.org/2002/07/owl#sameAs" } ,
        "o": { "type": "uri" , "value": "http://example.org/cat2" }
      }
    ]
  }
}


c'est le résultat de notre requete au format JSON !!! 
Yahou, Wahou, on a récupéré nos infos...
Et maintenant ???

Maintenant, nous plusieurs pistes :
1. modifier la requête pour qu'elle ne renvoie que les résultat qui nous intéressent, Thérèse.
2. traiter et mettre en forme ces données pour les afficher selon notre besoin,
3. créer la page de saisie pour insérer de nouvelles données sur notre serveur

Laquelle de ces trois pistes souhaitez-vous pour le prochain article ? 



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



11/03/2016

Un serveur fuseki RDF bigdata sur openshift

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


serveur de test : http://rdf-smag0.rhcloud.com/
- choisissez "Control Panel",
-  puis le Dataset "/ds",
- cliquez sur select,
-  un formulaire apparait, ou vous pouvez insérer des données (SPARQL Update) ou executer une requete (SPARQL Query))

repo github : https://github.com/scenaristeur/smag0-fuseki-rdf-openshift
(des problèmes de socket lorsque l'on tente d'utiliser la dernière version de Fuseki, donc on reste pour l'instant avec l'ancienne)


test 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 .
}
}



--> remplacez  le bloc  :
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 .

par les triplets que vous souhaitez ajouter



test pour récupérer des données : 

select * where {?s ?p ?o}

ce qui nous donne pour une requete GET , et des données de retour au format JSON,
 par exemple pour une appli
 avec APP INVENTOR ou PROCESSING,
ou encore depuis une page web en javascript  l'url :

http://rdf-smag0.rhcloud.com/ds/query?query=select+*+where+%7B%3Fs+%3Fp+%3Fo%7D&output=json

Par exemple, on peut utiliser App Inventor pour récupérer les données : http://smag0.blogspot.fr/2016/03/bigdata-facile-une-application-android.html

ensuite, complétez-là pour mettre à jour les données du serveur :
http://smag0.blogspot.fr/2016/03/big-data-facile-une-application-pour.html


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



04/03/2016

Dreamcatcher 3D sous Meteor

Objectif, un graphMaker en 3D.
un environnement 3D, dans lequel on peut se déplacer au milieu des graphes.
un mélange de http://smag0.meteor.com  (pour la gestion des triplets /graphes )
et de https://github.com/JohnRodney/Meteor-VR-Pano-demo (pour les deplacements)
https://github.com/JohnRodney/meteor-vr-demo  (pour la gestion de objets cubes)

--> securisation et authentification -> meteor
--> 3D avec thrrejs


  1. installer meteor 
  2. creez votre app :  meteor create mon app
  3. aller dedans : cd monapp
  4. ajouter le package THREEJS : meteor add limemakers:three



Mon carnet, je l'ai volontairement perdu

le carnet volant .

Achetez un carnet,
ou trouvez-en un chez vous.
Piquez le à votre fille
 ou reliez quelques feuilles A4,
 pliées en 4 ...
 et notez dedans quelques idées,

 ce qui vous vient par la tête,
 ou ce qui vous vient par le coeur.
Notez ces pensées dans le carnet sus mentionné,
 comme elles vous viennent,
 retravaillez-les
 si vous le Souhaitez,
barrez,
 rognez,
 tournez,
ecrivez-les
 à l'envers,
 en verlan,
 en chantant,
 en notes,
en dessins,
 en uml,
 en mindmap
 ou en Rdf
et terminez
 par le mention :

 " ce carnet à été perdu volontairement.
Si vous lisez ceci,
 deux possibilités :
        - soit vous avez commencé par la fin,
        - soit vous avez lu depuis le début.

Si vous avez commencé par la fin,
 et que cela vous plait,
je vous invite à consulter le début.

Si vous avez déjà commencé par le debut,
 et que votre lecture vous a fait réagir,
 l'initiateur de ce carnet
 vous invite à écrire,
comme lui-même l'a fait,
 et a par la même occasion
 provoqué en vous
le plaisir
 de découvrir
de nouveaux points
 de vue,
externes aux vôtre,
 et à pu ainsi
 vous ouvrir
 une fenêtre sur le monde,
 ou sur un monde différent du voöôtre.

 Ce plaisir,
 vous pouūüvez vous aussi
 le procurer à des inconnunus,
 nus ou non...
n'est pas la gestion!

Pratuitement ou gresque!
 Oui mÔdÃm on vous demande
juste d'écrire à votre tour
 dans ce carnet,
 d'y inscrire quelques unes de vos pensées,
et de continuer la chaîne de 2 manières :
       - La première en perdant à nouveau ce carnet,
 pour qu'il soit trouvé par quelqu'un d'autre,
 et la seconde en renvoyant un autre carnet
que vous trouverez chez vous,
 piquerez à votre fille,
votre frère,
votre patron,...
 à la caissière de chez Leclerc,
ou au pilote
de l'avion,
au photo
graphe, à l'ontologiste...

en renvoyez
le à l'adresse postale
que vous trouverez à cette adresse
 web : http://smag0.blogspot.fr/NS/Personne/DavidF "


-- ( fin du message à noter à la fin du carnet ) --

 --> remplacez "David"
 par votre identifiant
sur le site Smag0
si vous en avez un,
ou trouvez une façon habile,
 facile.
 subtile,
maligne,
 pour donner à votre lecteur
 une dernière fois
 l'occasion de se creuser la tête
 avec vos écrits
ou votre esprit,
 de vous connaître.

Votre lecteur,
 qu'il ai apprécié vos écrits,
 ou se soit amusé
avec votre prouesse finale,
aura passé un bon moment,
ou aura,
tout du moins,
 j'ose espérer,
fait suivre
votre carnet en le perdant à son tour.

Et vous,  ???
vous aurez lancé une idée !
Peut-être fera-t-elle le tour du monde,
 si vos lecteurs sont captivés.
 Ira-t-elle dans l'espace ???

Imaginez,
 si un jour,
lorsque le ou les carnets
dont vous êtes l'initiateur
sera ou seront
 terminés,

 quelqu'un vous les renverra,

 et vous pourrez découvrir

 à votre tour

les idées

 et les pensées

que les vôtres


 auront apporté


 aux différents
 possesseurs temporaires
de votre carnet.