Table des matières
Vala
Vala est un langage de programmation compilé, qui réutilise la « plateforme » GObject du projet GNOME.
Résoudre les redirections (302) avec libsoup
Dans l'exemple ci-dessous, nous allons utilisé le signal got-headers pour savoir si une ressource est directement accessible ou une redirection (302) est mise en place.
- redirect.vala
/* * valac --pkg=glib-2.0 --pkg=libsoup-2.4 redirect.vala * * Find the real URL (it even works with 302 HTTP status code). */ using GLib; using Soup; public class Request : Object { private string url; public Request (string resource) { this.url = resource; } private string get_real_uri (string resource) { Session session; Message msg; string new_url = null; /* Create Soup.* objects */ session = new Session (); msg = new Message ("GET", resource); /* Signal */ msg.got_headers.connect (() => { /* 302 */ if (msg.status_code == Status.FOUND) { new_url = msg.response_headers.get_one ("Location"); /* Finish processing request */ session.cancel_message (msg, Status.CANCELLED); } }); session.send_message (msg); if (new_url == null) { new_url = "%s".printf (resource); } return new_url; } public void send () { /* Find the real URI */ stdout.printf ("%s\n", get_real_uri (this.url)); } public static int main (string[] args) { //string uri = "http://ftp.netbsd.org/pub/NetBSD/security/advisories/NetBSD-SA2016-005.txt.asc"; //string uri = "http://rf.proxycast.org/1175697431602405376/13940-16.06.2016-ITEMA_21011329-0.mp3"; string uri = "http://www.podtrac.com/pts/redirect.mp4/201406.jb-dl.cdn.scaleengine.net/bsdnow/2016/bsd-0146.mp4"; var r = new Request (uri); r.send (); return 0; } }
Les expressions régulières
Dans cet exemple, nous allons voir comment récupérer un morceau d'une chaîne de caractères, en nommant le pattern comme on peut le faire sous Python.
Je vous conseille de parcourir cette page (Cf. Named subpatterns).
- regex.vala
/** * valac --pkg=glib-2.0 regex.vala * **/ public static int main (string[] argv) { GLib.Regex re; GLib.MatchInfo info; string data = "!system=DEVFS subsystem=CDEV type=CREATE cdev=video90"; // Python's way :) string pattern = "subsystem=CDEV type=CREATE cdev=(?P<device>video[0-9]+)"; try { re = new GLib.Regex (pattern); if (re.match (data, 0, out info)) { stdout.printf ("%s\n", info.fetch_named ("device")); } } catch (GLib.RegexError e) { stderr.printf ("Error: %s\n", e.message); } return 0; }
valac --pkg=glib-2.0 regex.vala ./regex video90
Afficher le nombre de cœur du processeur
Ce bout de code fonctionne uniquement sous FreeBSD.
- cpu.vala
/** * Compile with: * valac --pkg=glib-2.0 cpu.vala * * Get number of core processor. **/ private static string nb_cpu (string data) { string[] tokens; string cores = null; tokens = data.split (": "); if (tokens.length == 2) { cores = tokens[1]; } return cores; } public static int main (string[] argv) { string cmd = "/sbin/sysctl hw.ncpu"; string cores; string std_err = null; int status; try { GLib.Process.spawn_command_line_sync (cmd, out cores, out std_err, out status); if (status == 0) { stdout.printf ("%s", nb_cpu (cores)); } } catch (GLib.SpawnError e) { stderr.printf ("Error: %s\n", e.message); } return 0; }
Fichier / dossier
Déterminer le MIME type d'un fichier
On doit charger les modules glib-2.0 et gio-2.0.
/* * Exemple d'utilisation pour deviner le type de fichier. * * valac --pkg glib-2.0 --pkg gio-2.0 content-type.vala */ class ContentType : Object { public static int main (string[] argv) { if (argv.length == 2) { GLib.File file = File.new_for_commandline_arg (argv[1]); try { GLib.FileInfo file_info = file.query_info ( FileAttribute.STANDARD_CONTENT_TYPE, FileQueryInfoFlags.NONE, null); string content_type = file_info.get_content_type (); if (content_type == "image/png") { stdout.printf ("Ok\n"); } else { stderr.printf ("No\n"); } } catch (Error e) { stderr.printf ("%s", e.message); } } else { stderr.printf ("%s FILE\n", argv[0]); } return 0; } }
On obtient pour une image PNG le résultat suivant :
./content-type ristretto.png Ok
Or si l'on « porte » cette portion de code en C, le test ne va pas fonctionner, il faut utiliser la fonction g_content_type_is_a.
Depuis Vala >= 0.12 GLib.g_content_is_a est obsolète, on doit plutôt utiliser GLib.ContentType.is_a.
On remplace ce test dans l'exemple ci-dessus :
... if (content_type == "image/png") { stdout.printf ("Ok\n"); } else { stderr.printf ("No\n"); } ...
par
... if (GLib.ContentType.is_a (content_type, "image/png")) { stdout.printf ("Ok\n"); } else { stderr.printf ("No\n"); } ...
Connaître le nom du répertoire courant
On utilise le module glib-2.0.
public class Main : Object { public static int main (string[] argv) { string current_dir = GLib.Environment.get_current_dir (); stdout.printf ("%s\n", current_dir); return 0; } }
Pour afficher le résultat de l'exemple précédent sous forme d'uri. On doit charger en plus le module gio-2.0.
public static int main (string[] argv) { string current_dir = GLib.Environment.get_current_dir (); GLib.File file = GLib.File.new_for_path (current_dir); stdout.printf ("%s\n", file.get_uri ()); return 0; }
Créer un dossier
Il faut charger les modules glib-2.0 et gio-2.0.
public static int main (string[] argv) { // le nouveau dossier à créer string child_dir = "nouveau"; string current_dir = GLib.Environment.get_current_dir (); GLib.File file = GLib.File.new_for_path (string.join ("/", current_dir, child_dir)); try { // le dossier est créé maintenant file.make_directory (); } catch (GLib.Error e) { error ("%s\n", e.message); } return 0; }
Déterminer l'origine d'une IP
Le service est désormais payant.
Cet exemple montre comment obtenir l'origine d'une IP. On doit installer utiliser les modules suivants :
- glib-2.0
- libsoup-2.4
- json-glib-1.0
- geoip.vala
/* * Compile with: * valac --pkg=glib-2.0 --pkg=libsoup-2.4 --pkg=json-glib-1.0 geoip.vala * * Get country code from IP address. * */ public class GeoIP : Object { private const string HOSTNAME = "www.telize.com"; private string address; private Soup.URI uri; #if LIBSOUP_2_42 private Soup.Session session; #else private Soup.SessionSync session; #endif private Soup.Message msg; public GeoIP () { /* Create Soup.URI object */ address = "http://%s".printf (HOSTNAME); this.uri = new Soup.URI (address); /* Create session object */ #if LIBSOUP_2_42 this.session = new Soup.Session (); #else this.session = new Soup.SessionSync (); #endif } public void run (string resource) { string content = null; content = send_query (resource); if (content != null) { parse_json (content); } } private void parse_json (string data) { Json.Parser parser; Json.Node node; unowned Json.Object obj; parser = new Json.Parser (); try { parser.load_from_data (data); } catch (GLib.Error e) { stderr.printf ("Error: '%s'\n", e.message); } node = parser.get_root (); if (node.get_node_type () == Json.NodeType.OBJECT) { obj = node.get_object (); foreach (unowned string name in obj.get_members ()) { if (name == "country_code") { unowned string item; item = obj.get_string_member (name); stdout.printf ("%s\n", item.down ()); } } } } private string send_query (string resource) { string content = null; this.uri.set_path ("/%s".printf (resource)); msg = new Soup.Message.from_uri ("GET", this.uri); this.session.send_message (msg); #if VALA_0_22 if (Soup.Status.OK == msg.status_code) { #else if (Soup.KnownStatusCode.OK == msg.status_code) { #endif content = (string) msg.response_body.flatten ().data; } return content; } } void main (string[] argv) { string path = "geoip"; GeoIP ip; ip = new GeoIP (); ip.run (path); }