SRA Lab Open Source Code

27Jan/110

Dynamic OR’d Queryset Creation with Django

To complete posts and comments published on Elf Sternberg's blog, this is the method I found to create dynamic complex queryset with Django (Q and or):

field = 'toto'
qs = Q(**{field + '__slug': 'AL'})
qs |= Q(**{field + '__isnull': True})
Document.objects.filter(qs)

PS: You can start with qs = Q() if you need a loop.

Tagged as: No Comments
17Jan/110

libmodbus v2.9.3 is out!

During this development cycle, I've received more feedback than for any other releases. That's really cool, thank you! With this new release, you can consider to migrate from the previous 2.0.x series for your applications.

libmodbus v2.9.3 (2011-01-14)

  • Major rewriting of the message reading (no more timeouts on exception)
  • New function to reply to an indication with an exception message modbus_reply_exception()
  • New function modbus_get_header_length(modbus_t *ctx)
  • New functions to manipulate data:
    • MODBUS_GET_INT32_FROM_INT16
    • MODBUS_GET_INT16_FROM_INT8
    • MODBUS_SET_INT16_TO_INT8
  • Fix GH-2. Read/write were swapped in _FC_READ_AND_WRITE_REGISTERS
  • Install an ignore handler for SIGPIPE on *BSD.
    Original patch by Jason Oster.
  • Fix closing of Win32 socket.
    Reported by Petr Parýzek.
  • Fix unit identifier not copied by the TCP server.
    Reported by Antti Manninen
  • Fix missing modbus_flush() in unit tests.
  • Fixes for OpenBSD by Barry Grumbine and Jason Oster

This time, the release is not only availabe as tarball but also as Fedora and Ubuntu packages on the download page.

For the next release, I've already merged my ipv6 branch (based on the work of Florian Forster), the rtai branch of Chris Cole is waiting for review (ah, RTAI, like in the good old days :) and I hope to take care of the gtk-doc work done by Luis Matos.

14Jan/110

libsoup and Django

If you need to interface C code with a Django app, you should consider to use libsoup. It's a nice HTTP client/server library based on GObject and integrated with the glib main loop.

This is the code I used to authenticate with libsoup against my Django application (and the code is similar for any forms):

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <glib.h>

#include <libsoup/soup.h>
#include <libsoup/soup-auth.h>

static char* django_get_csrftoken_from_body(SoupMessage *msg)
{
    char *csrftoken = NULL;
    char *p_found;

    p_found = g_strrstr_len(msg->response_body->data,
                msg->response_body->length,
                "csrfmiddlewaretoken");
    if (p_found != NULL) {
    csrftoken = g_strndup(p_found + strlen("csrfmiddlewaretoken' value='"),
                  strlen("c711343cd20077a3aa869fcc9b931ff3"));
    }
    return csrftoken;
}

static int django_authenticate(SoupSession *session, const char *base_uri)
{
    char *uri;
    SoupMessage *msg;
    char *csrftoken;

    uri = g_strconcat(base_uri, "login/", NULL);
    msg = soup_message_new(SOUP_METHOD_GET, uri);
    soup_session_send_message(session, msg);
    printf("Login Status Code: %d\n", msg->status_code);
    if (msg->status_code != 200) {
    g_object_unref(msg);
    g_free(uri);
    return -1;
    }

    csrftoken = django_get_csrftoken_from_body(msg);
    g_object_unref(msg);

    printf("CSRF token %s\n", csrftoken);

    msg = soup_form_request_new("POST", uri,
                "username", "MYUSERNAME",
                "password", "MYPASSWORD",
                "csrfmiddlewaretoken", csrftoken,
                NULL);
    soup_session_send_message(session, msg);
    printf("POST Login Status Code: %d\n", msg->status_code);
    printf("Message %s\n", msg->response_body->data);

    g_free(csrftoken);
    g_object_unref(msg);
    g_free(uri);

    return 0;
}

int main(int argc, char** argv)
{
    SoupSession *session;
    SoupCookieJar *jar;

    g_type_init();

    session = soup_session_sync_new();

    /* Accept all cookies */
    soup_session_add_feature_by_type(session, SOUP_TYPE_COOKIE_JAR);
    jar = SOUP_COOKIE_JAR(soup_session_get_feature(session,
                           SOUP_TYPE_COOKIE_JAR));
    soup_cookie_jar_set_accept_policy(jar, SOUP_COOKIE_JAR_ACCEPT_ALWAYS);

    django_authenticate(session, "http://localhost:8000/");

    soup_session_abort(session);
    g_object_unref(session);

    return 0;
}
5Dec/102

New libmodbus 2.9.2 with win32 support and backends

OK, I don't care about Windows but I'm happy libmodbus offers a bit of Open Source to this platform so thank you to Tobias Doerffel for this contribution. The other major change is the use of an internal backend to isolate the transport layers (only serial RTU and TCP/IPv4 for now).

libmodbus 2.9.2 (2010-12-05)

  • Fix segfault in bandwidth-server-many-up on inet_ntoa() call
  • Fix unit test of report slave ID in RTU
  • Fix GH-3. Remove inclusion of config.h in modbus.h
  • Correctly detect if we are cross
  • compiling for win32 by Kirill Smelkov.
  • Rename modbus_[listen|accept] to modbus_tcp_[listen|accept]
  • Fix setting of the broadcast address
  • Remove slave argument from modbus_new_rtu()
  • Win32 support by Tobias Doerffel
  • Split source code around RTU and TCP (backends)
  • Check received function code

So let's run your MinGW!

13Oct/108

Current Tranformer

At home or at work, you probably have spotlights which indicate only 20W or 35W of power consumption, but sadly these spotlights are powered by a lower voltage and so they require a transformer (hidden in the ceiling, a cupboard or a hood) which in turn consumes around 40W.

I've recently designed an application (with libmodbus, glib and Django) to measure the power consumption from various sensors built by LEM. By doing some tests at home, I've confirmed my suspicions about a transformer permanently plugged into the mains (0.18 * 224 = 40.3W for total of 80W when both spotlights are turned on).

So, I've replaced the shunt plug with a switch between the main and the transformer and once again I have a perfect 0W when off!

Do you know how many electricity transformers do you have around you?

3Oct/100

Not utf-8 by default

On Ubuntu 10.04 (tested on server and desktop editions), the PostgreSQL database created by default, uses the SQL_ASCII encoding!
It's not possible to create new utf-8 databases so check the encoding with psql -l as PostgreSQL user and you can use the following radical way (drop everything) to fix this:

rm -rf /var/lib/postgresql/8.4/main
/usr/lib/postgresql/8.4/bin/initdb -E UTF8 /var/lib/postgresql/8.4/main/
Tagged as: No Comments
28Sep/100

New website for libmodbus project

The libmodbus project has now its own website www.libmodbus.org.

24Jun/101

The perfect git workflow!

It's strangely hard to find documentation on the git workflow to follow to keep a clean commit history when you want to merge external contributions.

First enable rebasing by default

As it's written on live.gnome.org, many users find that they happen to do "git pull --rebase" most of the time. Would be nice if "git pull" simply did that by default. You can set that up for the master branch of all your repositories by:

git config --global branch.master.rebase true

An upstream project

For our example, we've an upstream project with only one commit called C1

mkdir upstream
cd upstream
git init
touch hello.c
git add hello.c
git commit -m "C1"

Your fork

As contributor, you can fork as usual and commits your changes on a specific branch (newfeature).

git clone upstream fork
cd fork
git checkout -b newfeature
edit hello.c
git commit -a -m "C2"

When you're ready to ask for a pull request, sync with upstream project with a final "git pull" to help the maintainer to merge your patches (it's not mandatory).

Back to upstream

In the meantime, it's possible some new commits have landed in upstream.
As maintainer, you receive an email: "Could you merge my branch, please?", so you add the repository to your remote list to fetch the content:

git remote add fork ../fork/
git fetch fork

and create a branch to rebase the contributor work in a separated branch:

git checkout -b fork fork/newfeature
git rebase master
(and resolve if necessary)

You can now apply the fast-forward merge on your master branch
git checkout master
git merge fork

You're done with a nice commit history w/o ghost commits.

On the contributor side

Just delete your branch because after a rebase in upstream, your branch is certainly broken so it's time to cleanup:

git branch -D newfeature

Thanks to Staz and Dodji on #gnomefr chan.

27Apr/100

Succès pour les premières rencontres Django FR !

Bravo aux organisateurs de la première édition des rencontres Django FR, qui avaient même prévu des activités pour les accompagnateurs (conjoints, conjointes et enfants). Le planning des conférences a été fidèlement respecté malgré les aléas de la restauration.

L'ambiance était chaleureuse et l'évènement idéal pour rencontrer et discuter avec les djangonautes français (dont un belge du projet GNOME).

Ma présentation sur l'i18n/l10n avec Django et les photos de l'évènement par Providenz.

22Apr/100

Rencontres Django FR

Je serais présent, avec les djangonautes de Makina Corpus, aux http://rencontres.django-fr.org/ pour évoquer Django et la traduction.