Roxen Application Launcher 0.4.4

This is not the latest version of Roxen Application Launcher. You’ll find the latest version at the download page.

So, here’s a new release of the Roxen Application Launcher for Linux (RAL). The previous versions used my home made (sloppy so) HTTP client which didn’t handle redirects or secure connections – thank you tec for the feed back – since I had some major problems getting libsoup working with binary files like images and such. Binary files was heavily scrambled when read from or written to disk so I made my own simple HTTP client that kept the data as a byte array to prevent some underlying libraries (GLib) from fiddling with it.

But I solved the libsoup issue so now the RAL handles redirects and secure connections. This is how I solved it:

The libsoup issue

When uploading a file back to the Roxen server I use IOChannel (g_io_channel in plain C) instead of Gio. So the upload works like this:

13 lines of Vala
  1. var sess = new Soup.SessionSync();
  2. var mess = new Soup.Message(“PUT”, get_uri());
  3. mess.request_headers.append(“Cookie”, get_cookie());
  4. mess.request_headers.append(“Translate”, “f”);
  5. IOChannel ch = new IOChannel.file(local_file, “r”);
  6. ch.set_encoding(null); // Enables reading of binary data
  7. string data;
  8. size_t len;
  9. ch.read_to_end(out data, out len);
  10. mess.request_body.append(Soup.MemoryUse.COPY, data, len);
  11. sess.send_message(mess);

And that seems to work like a charm!

When downloading data it’s a bit more tricky! Of course I tried using IOChannel in this case also but that made no difference. Downloaded images ended up 4 bytes long! But then I thought: You can make your own C bindings in Vala (remember the Vala compiler generates C code) through what is called Vapi files. So what I did was writing a C function that takes a SoupMessageBody object/struct passed from Vala and writes the data part to a file given as argument.

19 lines of C/C++
  1. gboolean save_soup_data(SoupMessageBody *data, const char *file)
  2. {
  3. FILE *fh;
  4. if ((fh = fopen(file, “w”)) == NULL) {
  5. fprintf(stderr, “Unable to open file \”%s\” for writing!\n”, file);
  6. return FALSE;
  7. }
  8. int wrote = fwrite(data>data, 1, data>length, fh);
  9. if (wrote != (int)data>length) {
  10. fprintf(stderr, “wrote (%d) != data->length (%d). Data may have been “
  11. “truncated”, wrote, (int)data>length);
  12. }
  13. fclose(fh);
  14. return TRUE;
  15. }

And this was then made available to Vala by the following Vapi file:

6 lines of Vala
  1. [CCode (cprefix = “”, lower_case_cprefix = “”, cheader_filename = “”)]
  2. namespace Soppa // Soppa is Swedish for Soup 😉
  3. {
  4. [CCode (cname = “save_soup_data”)]
  5. public bool save_soup_data(Soup.MessageBody data, string file);
  6. }

And this is how the actual Vala code downloading the files looks like:

15 lines of Vala
  1. var sess = new Soup.SessionSync();
  2. var mess = new Soup.Message(“GET”, get_uri());
  3. mess.request_headers.append(“Cookie”, get_cookie());
  4. mess.request_headers.append(“Translate”, “f”);
  5. sess.send_message(mess);
  6. if (mess.status_code == Soup.KnownStatusCode.OK) {
  7. // Here I call the C function made available through the Vapi file
  8. if (Soppa.save_soup_data(mess.response_body, local_file)) {
  9. message(“The file was downloaded and written to disk OK”);
  10. }
  11. else {
  12. message(“Failed writing data to disk!”);
  13. }
  14. }

So that’s that on that! ;)

The notification

I also – just for fun – implemented a notification mechanism through libnotify. Since I believe that can be rather annoying it’s not activated by default but can easily be activated by a checkbox in the user interface.

The packages

The Roxen Application Launcher for Linux can be downloaded at the download page at Github where also the work in progress sources is available or downloaded below!

Roxen Application Launcher 0.4.4 23:06, Wed 13 January 2010 :: 373.5 kB

Stay black!