Automatiser la récupération et la compilation du kernel et de son patch GrSec

Plop à tous…

Petit truc de geek … un script pour automatiser la récupération du dernier kernel stable depuis le site kernel.org puis le dernier patch grsecurity à appliquer sur le kernel en question (qui sort généralement un jour après la release du kernel).
Sur ubuntu, il faut tout d’abord installer le paquet kernel-package :

sudo apt-get install kernel-package

Puis récupérer le script suivant (nommé chez moi recupKernel.pl dans la commande qui suivra) :

Il suffit ensuite d’executer la commande suivante :

perl recupKernel.pl && cd linux-* && make menuconfig && make-kpkg clean && make-kpkg --initrd --append-to-version "LoupZeur-grsec" kernel_image

Ce qui générera un fichier .deb qu’il faudra installer par un bon vieux dpkg -i.

PS: Lors de l’execution de la commande make menuconfig, une fenetre « bleu » apparaitra, il faudra selectionner la menu « security », puis grsecurity et choisir le niveau de sécurité « HIGH ».

PS2: Il faut aussi bien entendu selectionner ou deselectionner tout les modules inutiles (genre usb, support agp et … ).

Exemple de Bot d’Authentification et de clic en Php

Bonjour à tous …

Aujourd’hui ze bot « cliqueur » ^^, il s’agit en fait d’un bot qui s’authentifie en POST, récupère le cookie et va en get sur un lien (le clic quoi).

A quoi ça peut bien servir ?

Pour ma part, c’était pour récupérer une clé pour la closed beta de HON (un Dota avec des binaires pour linux, fallait pas rater ça!!) sur le site de Alienware, le problème, c’est que les clés étaient censé être disponible soit très tard dans la soirée, soit très tôt dans la matinée, et comme je n’aimais pas l’idée de rester sur le site à poireauter, j’ai fait ce que tout programmeurs auraient fait ^^, un sympatique script …

Les actions à faire étaient :

  1. Regarder sur le site si le nombre de clés disponibles étaient supérieur à 0
  2. S’authentifier
  3. Récupérer les clés

Ce qui donne donc le script suivant en tâche Cron toutes les 5 minutes (fallait juste pas oublier de couper le script après réception des clés ^^) :

]*>Closed Beta Keys Remaining[\W\w]*]*>([0-9]+)|iU',$hon,$retour);

if($retour[1]!=0)
{
	$socket = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create socket\n");
	if(socket_connect($socket,"www.alienwarearena.com","80"))
	{
	//La requete de post pour ce logger
		$postReq = "POST /cmd/account/login/ HTTP/1.1\r\n";
		$postReq.= "Host: www.alienwarearena.com\r\n";
		$postReq.= "Connection: Keep-Alive\r\n";//comme ça on se reconnecte direct 😉 Pipelinning ROXX!!
		$postReq.= "Content-type: application/x-www-form-urlencoded\r\n";
		$postReq.= "Content-Length: ".strlen($stringLoginPost)."\r\n\r\n";
		$postReq.= $stringLoginPost."\r\n";
		socket_write($socket,$postReq);
		socket_recv($socket,$retour,1024,0);
	//la récupération de la valeur du cookie
		preg_match("#Set-Cookie: PHPSESSID=([^;]*); path=/#",$retour,$tabRet);
	//On va à la page de récupération des clés ^^
		$getReq = "GET /cmd/account/get-beta-key/hon/ HTTP/1.1\r\n";
		$getReq.= "Host: www.alienwarearena.com\r\n";
		$getReq.= "Cookie: PHPSESSID=".$tabRet[1]."\r\n";
		$getReq.= "Connection: Close\r\n\r\n";
		socket_write($socket,$getReq);
		socket_recv($socket,$retour,1024,0);

		mail(MAILADRES,"HON KEY!!","You got an HON KEY : ".$retour);
	}
        socket_close($socket);
}
?>

Donc voilà … le script reste une idée (qui a fonctionné dans mon cas) à modifier selon les cas, avec curl ça aurait été plus court, mais faire mumuse avec les sockets ça n’a pas de prix …

Installer un donuts sur son G1 (CyanogenMod)

Bijour …

Bé voilà, prochainement (voir depuis peu ^^) google a release sa nouvelle mise à jour de l’OS Android, avec pas mal de modifications dedans (plus rapide, bouffant moins de ressources, plus ergonomique, plus tout quoi …).

Etant très peu enclin à compiler la chose, je me suis tourné vers le mod de cyanogen qui publie toutes ses modifications dans un git en s’efforçant de suivre une idée : fournir quelques chose de « stable » pour l’instant que des béta ( ironie inside ^^), de sécurisé (utilisant un kernel à jour ^^ pas comme celui fournit par défaut par google), et avec plein de patch divers et variés (les principaux points forts son décrit ici).

Je ne vais pas décrire une énième fois l’ensemble des points forts d’android (on lit ça partout), je vais juste décrire les étapes d’une mise à jour/installation (sans perte de données, donc on garde gmail et compagnie ainsi que ses données : appli installé et …).

Continuer la lecture de Installer un donuts sur son G1 (CyanogenMod)

Youtube et JavaFX via MediaView

Bijour …

Je suis encore et toujours en train de m’amuser avec JavaFX, et comme je suis un gros noob et que j’ai rien réussi à faire avec Jiwa (et que deezer ne me file toujours pas de clé pour leur API), j’ai décidé de me tourner vers Youtube qui fournit une API ( les clés pour leur API ne semblent pas à servir pour grand chose, l’essentiel de l’API (un fichier XML/ATOM) étant accessible sans être identifié …).

L’appli finale ressemble étrangement à celle crée pour Jiwa, à la seul différence qu’elle embarque un lecteur vidéo (depuis l’API 1.2.1 de javaFX il est possible de jouer des flux rtsp … le support est donc encore un peu chaotique (il manque des codec) : la vidéo joue sans le son ou l’inverse, le chargement du média s’effectue mais il n’arrive pas à le lire …, certaine fonction lié au média ne fonctionne pas (onStalled et onBuffering)).

La tête de l’application finale (super moche … encore un concept) :

youtubeFX

Néanmoins malgrès tout les problèmes du support vidéo streaming, l’effet escompté est bien là … la lecture de la vidéo bouffe beaucoup moins de ressource (faut dire que la vidéo est au format mpeg4-sp (176*140) pour les téléphones portable donc … ;)).

La recherche des vidéos est effectuée en XML, j’aurais bien voulu utiliser l’objet AtomTask pour récupérer les données contenues dans le XML renvoyé par Youtube, mais malheureusement, dans leur API (celle de javaFX, pas de YouTube ^^), ils n’ont pas prévue qu’il puisse y avoir plusieurs médias dans le « content », donc j’ai du le parser à la main et faire un beau hack pour choper le flux.

Sur le plan technique, au lieu d’utiliser le MediaView, j’aurai pu utiliser la technique de Rakesh Menon en affichant une page web avec le player « chromeless de youtube » via l’API JS, mais ça aurait enlevé l’intêret de l’application puisque le but est de se débarasser du lecteur Flash.

Le temps de développement est super court (j’ai du mettre plus de temps à écrire l’article sur le blog qu’à developper l’appli ;)), par contre, y’a déjà pas mal de hack pour rendre l’appli plus rapide/réactive, et il n’y a malheureusement aucune fonction qui permettent de déterminer si on charge la vidéo ou non (le onBuffering ne fonctionne pas :s).

Donc c’est assez naze d’avoir une appli de streaming sans état d’avancement dans le chargement du média mais comme y’a pas grand chose en français sur JavaFX et les média … je post le code (en espérant que le support de Java soit meilleur plus tard ^^) :

/*
 * Main.fx
 *
 * Created on 9 oct. 2009, 20:18:51
 */

package youtubefx;

import javafx.stage.Stage;

import javafx.scene.Scene;
import javafx.scene.text.Text;
import javafx.scene.media.MediaPlayer;
import javafx.data.pull.PullParser;
import javafx.io.http.HttpRequest;
import javafx.data.pull.Event;
import javafx.scene.control.Button;
import javafx.scene.control.TextBox;
import javafx.scene.layout.VBox;
import javafx.scene.layout.HBox;
import javafx.scene.control.ListView;
import javafx.ext.swing.SwingListItem;
import javafx.scene.input.MouseEvent;
import javafx.scene.media.MediaView;
import javafx.scene.media.Media;
import javafx.scene.control.ProgressBar;
import javafx.scene.Group;
import javafx.scene.shape.Rectangle;
import javafx.scene.paint.Color;
import javafx.scene.CustomNode;
import javafx.scene.Node;

/**
 * @author Gaetan Grigis
 */
class Splash extends CustomNode {
    var rect = Rectangle {x:0,y:0,width: 400,height: bind scene.height,fill: Color.BLACK};
    var txt = Text{content: "Hello this is just a simple test to use MediaView\n"
                          "and MediaPlayer with Youtube\n \n"
                          "As the support of streaming by JavaFX is new\n"
                          "sometimes it crash or doesn't work as expected\n"
                          "because of unsupported codec (video or music\n"
                          "isn't played in this case ...)\n \n"
                          "(Click somewhere here to close this ...\n"
                          "and try this ...)",x: 50,y: 50,fill: Color.AQUAMARINE};
    var groups = Group {
        content: [rect,txt],
        onMouseClicked: function( e: MouseEvent ):Void {rect.width=0;txt.content="";txt.x=0;txt.y=0}
    }

    override function create():Node {return groups;}
}
var item : SwingListItem[] = [];
var xml : PullParser = PullParser {documentType: PullParser.XML};
var mus = [];
//UI items
var scene = Scene {width: 400,height: 250};
var searchTxt = TextBox{width:bind (scene.width - 276),text: "Type your text .."};
var searchBtn = Button{text: "Search",width: 100,action: function(){searchItem(searchTxt.text)};};
var listView : ListView = ListView{width:bind (scene.width-176),height: bind (scene.height - searchTxt.height),items: bind item};
var SearchBox = HBox {content: [searchTxt,searchBtn],width: bind scene.width};
var PlayBox = VBox{content:[SearchBox,listView],width: bind (scene.width - 176),height: bind scene.height};
var player = MediaPlayer{autoPlay:true};
var info = Text {content: bind "{player.currentTime.toSeconds()}/{player.media.duration.toSeconds()} Sec.\nStatus : {player.status}\nClick on the progressBar\nif it doesn't start\n\tStatus 2 = playing\n\tStatus 0 = Loading/Crashed", };
var pg = ProgressBar{progress: bind ProgressBar.computeProgress(player.media.duration.toSeconds(),player.currentTime.toSeconds()),onMouseClicked:function(e:MouseEvent){if(player.status!=2){player.play();}else{player.pause();}}};
scene.content = HBox{content:[Splash{},PlayBox,VBox{content: [MediaView{visible:true, cache: true, mediaPlayer: player},info,pg]}]};

function searchItem(search: String)
{
    item = [];//on reset à la barbare 😉
    var connexion : HttpRequest = HttpRequest {
        method: HttpRequest.GET
        location: "http://gdata.youtube.com/feeds/api/videos?v=2&lr=en&format=6&orderby=published&safeSearch=strict&q={search}&max-results=50"
        onInput: function(is: java.io.InputStream) {
            try {
                xml.input = is;
                var it = SwingListItem{};
                var i  = 0;
                xml.onEvent = function(event: Event) : Void{
                    if( event.qname.prefix == "media" )
                    {
                        if(event.qname.name == "content" and event.typeName == "START_ELEMENT" and event.getAttributeValue("type") == "video/3gpp" )
                        {
                            //can't get the yt:format, so as we know that mpeg is second we just increment ...
                            it.value = event.getAttributeValue("url");
                            i++;
                        }
                        if(event.qname.name == "title" and event.text!="" and event.typeName == "TEXT"){it.text = event.text;}
                        if(it.text !="" and it.value!="" and i > 1 ){
                            insert it into item;it = SwingListItem{};
                        }
                    }
                };
                xml.parse();
            } finally {is.close();}
        }
    };connexion.start();
}

listView.onMouseClicked = function (e:MouseEvent):Void{
    player.stop();
    listView.disable=true;
    //hack to stop playing while another is loading
        player.media.source = null;
        player.media = null;
    player.media = Media{source:item[listView.selectedIndex].value.toString(),};
    player.play();
    listView.disable=false;
}
Stage {title: "ytFX",scene: scene,onClose:function(){player.pause();player.media.source = null;player.media = null;}}

Comme dit, le code est moche, y’a du hack partout plein de syntaxe différente pour des trucs similaires …

Tor Proxy et randomiser le choix des serveurs de sorties

Bonjour,

Je n’utilise plus le logiciel tor depuis que je suis tombé sur le sympatique tortunnel de Moxie qui permet d’avoir un débit super intéressant par rapport à tor (tout en gardant le chiffrement, mais en perdant les intermédiaires … et donc une partie de l’anonymat, mais tant que la connexion passe par un autre pays ;)), l’un des problèmes étant le fait que le logiciel plante quelque fois (ou la connexion est coupée après un certain temps ou débit).

Donc tout d’abord le logiciel, il faut soit le compiler soit installer le paquet qui se trouve sur mon dépôt :

sudo add-apt-repository ppa:cipher.16/ppa
sudo apt-get update && sudo apt-get install tortunnel

Ensuite, il faut récupérer la liste des sorties de tor ayant un débit intéressant, un csv est dispo sur blutmagie, mais je voulais réviser le langage perl … ce qui donne :

#!/usr/bin/perl
# Create a user agent object
require HTTP::Request;
use LWP::UserAgent;

# Create a request
my $req = HTTP::Request->new(GET => "http://torstatus.kgprog.com/index.php?SR=Bandwidth&SO=Desc");
 my $ua = LWP::UserAgent->new;
 $ua->agent("Firefox/4.0");
my $res = $ua->request($req);
if ($res->is_success) {
	my $text = $res->content;
        my $recherche = "ip=([0-9.]*).*Exit Server";
	while($text =~ m/($recherche)/g)
	{
		print $2."\n";
		pos($text)+1;
	}
} else {
   print "Le site est HS :s\n";
}

On enregistre le fichier (pour moi tor.pl), on execute et on lance le proxy :

perl tor.pl > /tmp/tor.txt && while true; do torproxy `cat /tmp/tor.txt |head -10 |tail -n $(expr ${RANDOM} % 10)|head -1`; done;

Et hop, ici on choisit un serveur parmis les 10 premiers, et on l’assigne à torproxy … etvoilà, profitez d’un anonymat (relatif) à la vittesse de votre ligne adsl (ou presque ^^).

Jouer avec JavaFX, JSON, HTTP et Jiwa

Bijour,

Au commencement de mon blog Dieu créa la terre, le ciel, linux, javaFX venait de sortir et j’avais publié quelques liens intéressant sur la bestiole, mais j’avais pas fait grand chose avec.

Aujourd’hui … j’ai essayé de faire un player musical version Desktop du genre Spotify en JavaFX (parce que Deezer ou Jiwa font pas mal ramer les machines utilisant flash sous linux), une appli qui devait se fournir sympatiquement en musique chez Jiwa.

Plantage du décors et quelques avancement du soft :

La recherche de titres, d’albums ou artistes se fait via une requête en post à l’url http://www.jiwa.fr/track/search, et la réponse est de type :

{"page":[
{"trackId":133337,
"songId":1337,
"songName":"les kikoolols attaquent!!",
"artistId":51337,
"artistName":"KikoololMaster",
"secArtistsNames":null,
"albumId":7331,
"albumName":"Les Kikoolols vaincront",
"songPopularity":69,
"itunesTrackUrl":null,
"albumReleaseDate":"1969-01-01",
"duration":"404",
"hidden":"0",
"sourceId":null}],
"total":1,
"min":0,
"max":1,
"pageSize":25,
"success":true}

Il faut donc faire la requête http POST, avec le paramètre Q = notre recherche :

var connexion : HttpRequest = HttpRequest {
        method: HttpRequest.POST
        location: locationSearch
        onOutput: function(os: java.io.OutputStream) {
            var urlConverter = URLConverter{};
            var pair = Pair {name: "q",value: "Les kikoo roxe !!"};
            var encodedMessage = urlConverter.encodeParameters([pair]);
            os.write(encodedMessage.getBytes());
            os.close();
        }
        onInput: function(is: java.io.InputStream) {
            //récupération du JSON
        }
    };connexion.start();

Rien de complexe jusque-là … on récupère donc notre JSON, grâce à l’objet PullParser :

try {
                json.input = is;
                var tmpElmt = "";
                var i=0;
                json.onEvent = function(event: Event) : Void{
                    if( event.type == PullParser.TEXT ){

                        if(event.name == "artistName"){tmpElmt.concat(event.text);}
                        else if (event.name == "artistName"){tmpElmt=tmpElmt.concat("Artiste : {event.text.trim()} ");i++;}
                        else if (event.name == "albumName"){tmpElmt=tmpElmt.concat("Album : {event.text.trim()} ");i++;}
                        else if (event.name == "songName"){tmpElmt=tmpElmt.concat("Titre : {event.text.trim()} ");i++;}
                        if(i==2){insert tmpElmt.replaceAll("\n", "").trim() into item;i=0;tmpElmt="";}
                    }
                };
                json.parse();
            } finally {is.close();}

On récupère donc le nom de l’album, du chanteur et le titre de la chanson (les autres paramètres sont pour plus tard) et on l’insert dans un tableau nommé « mus » ….

Le problème pour la suite, c’est la récupération de la chanson, qui se passe en deux étapes : la récupération des informations liées au songId et la récupération du mp3.

Grâce au songId l’on vient de choper dans le JSON, on a accès à l’étape suivante via une requête POST à l’url http://m.jiwa.fm/token.php où l’on envoit le paramètre s avec l’id « songId » retourné dans le JSON plus haut, ce qui donne comme réponse un string de la forme : « unMD5=8 chiffres=un zero=7 chiffres=3 chiffres », ce qui permet apparement de crée l’url de téléchargement de la chanson :

http://m.jiwa.fm/play.php?r=8 chiffres&s=le songId&t=un md5&m=7 chiffres&from=0, qui renvoit direct le mp3 ou -1 si les paramètres ne sont pas bon :s

Le gros problème étant que le md5 retourné par token.php, n’est pas celui à fournir dans l’url du play.php.

Il faut donc ouvrir le player swf ( ou se baser sur iJaw pour les flemmards comme moi ) pour choper la « clé », et récupérer le flux.

Le code complet en javaFX (pour le moment ^^, permet de récupérer le flux, et de le lire … en executant le jar!!! Via une compilation direct depuis netbeans, il ne trouve pas le mp3) :

/*
 * Main.fx
 *
 * Created on 3 oct. 2009, 13:07:02
 */

package jiwafx;

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.io.http.HttpRequest;
import javafx.io.http.URLConverter;
import javafx.data.Pair;
import javafx.scene.control.ListView;
import javafx.ext.swing.SwingListItem;
import javafx.data.pull.PullParser;
import javafx.data.pull.Event;
import javafx.scene.control.Button;
import javafx.scene.control.TextBox;
import javafx.scene.layout.VBox;
import javafx.scene.layout.HBox;
import javafx.io.http.HttpHeader;
import javafx.scene.input.MouseEvent;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.Media;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.FileOutputStream;
import java.io.BufferedInputStream;
import java.io.InputStream;

/**
 * @author cipher16
 */
//Global var
var item : SwingListItem[] = [];
var mus = [];
//UI items
var scene = Scene {width: 250,height: 250};
var searchTxt = TextBox{width:bind (scene.width - 100),text: "Entrer votre recherche"};
var searchBtn = Button{text: "Rechercher",width: 100,action: function(){searchAlbum(searchTxt.text)};};
var listView : ListView = ListView{width:bind scene.width,height: bind (scene.height - searchTxt.height),items: bind item};
var SearchBox = HBox {content: [searchTxt,searchBtn],width: bind scene.width};
var player = MediaPlayer{autoPlay:true,onBuffering:function(d){println("Encore :  {d}")}};
scene.content = VBox{content:[SearchBox,listView],width: bind scene.width,height: bind scene.height}

function launchDl(url:String) : Void
{
    var ua = HttpHeader{name:"User-Agent",value:"Mozilla/5.0 (X11; U; Linux i686; fr; rv:1.9.1.3) Gecko/20091020 Ubuntu/9.10 (karmic) Firefox/3.5.3"};
    HttpRequest {
        method: HttpRequest.GET
        headers: [ua]
        location: url
        onInput: function(is: java.io.InputStream) {
            var file = new FileOutputStream('jiwa.mp3');
            while(is.available()>0){
                file.write(is.read());
            }
            is.close();
        }
        onDone:function(){player.media = Media{source:"{__DIR__}jiwa.mp3"};player.play(); }
    }.start();
}

function getToken(id:String)
{
    var ret="";
    var referer = HttpHeader{name:"Referer",value:"http://www.jiwa.fm/res/widget/LightPlayer.swf?=1255325694463"};
    var ua = HttpHeader{name:"User-Agent",value:"Mozilla/5.0 (X11; U; Linux i686; fr; rv:1.9.1.3) Gecko/20091020 Ubuntu/9.10 (karmic) Firefox/3.5.3"};
    HttpRequest {
        method: HttpRequest.POST
        headers: [referer,ua]
        location: "http://m.jiwa.fm/token.php"
        onOutput: function(os: java.io.OutputStream) {
            var urlConverter = URLConverter{};
            var pairS = Pair {name: "s",value: id};
            var encodedMessage = urlConverter.encodeParameters([pairS]);
            os.write(encodedMessage.getBytes());
            os.close();
        }
        onInput: function(is: java.io.InputStream) {
            var buff = new BufferedReader (new InputStreamReader(is));
            var line = "";
            while((line = buff.readLine())!=null){
                ret="{ret}{line}";
            }
            is.close();
        }
        onDone: function()
        {
            launchDl(getTrackUrl(ret,id));
        }

    }.start();
}

function getTrackUrl(token:String,sid:String)
{
	var t_vals = token.split("=");
        var url="";
        if(t_vals.length>0)
        {
            var a = MD5.toHex('gwqd29ydg7sqys_qsh0');
            var b = MD5.toHex("{t_vals[0]}{a}{sid}");
            url = "http://m.jiwa.fm/play.php?r={t_vals[1]}&s={sid}&t={b}&m={t_vals[3]}&from=0";
        }
        return url;
}

function searchAlbum(search: String)
{
    item = [];//on reset à la barbare 😉
    HttpRequest {
        method: HttpRequest.POST
        location: "http://www.jiwa.fr/track/search"
        onOutput: function(os: java.io.OutputStream) {
            var urlConverter = URLConverter{};
            var pair = Pair {name: "q",value: search};
            var encodedMessage = urlConverter.encodeParameters([pair]);
            os.write(encodedMessage.getBytes());
            os.close();
        }
        onInput: function(is: java.io.InputStream) {
            try {
                var json : PullParser = PullParser {documentType: PullParser.JSON,input:is};
                var tmpElmt = "";
                var i=0;
                var it = SwingListItem{};
                json.onEvent = function(event: Event) : Void{
                    if( event.type == PullParser.TEXT or event.type == PullParser.INTEGER or event.type == PullParser.NUMBER ){
                        if (event.name == "artistName"){tmpElmt=tmpElmt.concat("Artiste : {event.text.trim()} ");i++;}
                        else if (event.name == "albumName"){tmpElmt=tmpElmt.concat("Album : {event.text.trim()} ");i++;}
                        else if (event.name == "songName"){tmpElmt=tmpElmt.concat("Titre : {event.text.trim()}");i++;}
                        else if (event.name == "songId"){i++;it.value="{it.value};{event.integerValue}"}
                        else if (event.name == "artistId"){i++;}//Lol xD Da Kikoolol Attack!!!
                        else if (event.name == "trackId"){i++;it.value="{event.integerValue}"}
                        if(i>=6){ it.text=tmpElmt.replaceAll("\n", "").trim(); insert it into item;i=0;tmpElmt="";it=SwingListItem{};}
                    }
                };
                json.parse();
            } finally {is.close();}
        }
    }.start();
}

listView.onMouseClicked = function(e:MouseEvent){
    player.stop();
    player.media.source = null;
    player.media = null;
    var ids = item[listView.selectedIndex].value.toString().split(";");
    getToken(ids[1]);
}

Stage {title: "JiwaFX",scene: scene}

Et tire cette tête là une fois executé (avec une recherche sérieuse) :

CaptureCe qui est pas trop mal pour un début … j’essaierais de faire la même chose pour deezer, avec la clé de l’API cette fois … histoire de réussir un truc plus abouti^^. J’ai juste posté le code pour aider les nouveaux en JavaFX (pour l’utilisation de requêtes POST en HTTP, très mal documenté par SUN et sur le parsing JSON, encore plus mal documenté …).

Le code est assez crade, car on est obligé d’attendre la fin (probable) de deux évènements (le chargement des deux pages token et play) pour lancer la musique.

L’un des gros problèmes actuel, c’est que Jiwa rejette les User-Agent en Java, ce qui fait que l’on ne peut pas directement filer l’url retourné par la fonction à la source du media, d’où l’obligation de passer par un fichier temporaire.

Voilà, amusez-vous bien

try {
json.input = is;
var tmpElmt = «  »;
var i=0;
json.onEvent = function(event: Event) : Void{
if( event.type == PullParser.TEXT ){

if(event.name == « artistName »){tmpElmt.concat(event.text);}
else if (event.name == « artistName »){tmpElmt=tmpElmt.concat(« Artiste : {event.text.trim()} « );i++;}
else if (event.name == « albumName »){tmpElmt=tmpElmt.concat(« Album : {event.text.trim()} « );i++;}
else if (event.name == « songName »){tmpElmt=tmpElmt.concat(« Titre : {event.text.trim()} « );i++;}
if(i==2){insert tmpElmt.replaceAll(« \n », «  »).trim() into item;i=0;tmpElmt= » »;}
}
};
json.parse();
} finally {is.close();}