Jan 17 2012

Snow leopard and Qt/PyQt 4.8.x won't work

If you try to install, even with Homebrew the latest version of Qt the 4.8.x, you may end up haing a surprise like that :

  1. ImportError: dlopen(/usr/local/lib/python/PyQt4/QtWebKit.so, 2): Symbol not found: _kCFWebServicesProviderDefaultDisplayNameKey
  2.   Referenced from: /Library/Frameworks/QtWebKit.framework/Versions/4/QtWebKit
  3.   Expected in: /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation

This is coming precisely from a Qt issue that don't seem to be resolved anytime soon, so anyway you're warned now, revert back to 4.7.x you have no choice. Except if you want to buy Lion :)

Vale


Jan 15 2012

Handle Celery-dependent tests in Django and with django-jenkins

So in your life, one of these days, you're going to realize you need tests, and that "maybe" you also need to test components that depend on several Celery tasks.

Well to help you make this day more productive and less painful, here's a few tips.

First to make it work with Django-celery, a pretty good but small documentation is available here http://ask.github.com/django-celery/cookbook/unit-testing.html it may seems small and not enough, but it actually is enough. To sum up all you need to make it work with ./manage.py test is to change the test runner to :

  1. TEST_RUNNER = 'djcelery.contrib.test_runner.CeleryTestSuiteRunner'

But it's not enough, soon when you think everything's over, you'll want to deploy and make it go through Jenkins's testing processes. Well i don't know about you but to me the django-jenkins project is quite a good one and i use it everyday but it has one flaw, it already as its designated TEST_RUNNER so if you try to execute your tests through ./manage.py jenkins it won't work and you'll get at least a Connection Refused error.

Here's how to fix this, the documentation says if you want to replace the TEST_RUNNER you may do so, but the class you'll use needs to inherit from django_jenkins.runner.CITestSuiteRunner and if you want the Celery tasks to work you need to use the djcelery.contrib.test_runner.CeleryTestSuiteRunner.

Fair enough, here's what i did. I created a new class :

  1. from django_jenkins.runner import CITestSuiteRunner
  2. from djcelery.contrib.test_runner import CeleryTestSuiteRunner
  3.  
  4. class MixedInTestRunner(CITestSuiteRunner, CeleryTestSuiteRunner):
  5.     pass

Why not ? and used it as such defining the new TEST_RUNNER by changing the settings's variable JENKINS_TEST_RUNNER to the newly created class.

And voilà.


Sep 24 2011

La puissance et le contrôle

En développement, comme dans beaucoup d'arts martiaux, on peut devenir fort assez rapidement. On peut se fixer des objectifs (une ceinture, une victoire / maitriser une technologie ou réaliser un projet perso) et les atteindre rapidement selon le language, le maître et l'implication qu'on y met.

Certains langages, tout comme certains arts martiaux, poussent à l'efficacité, à la rigueur ou aux résultats rapides. En Tae Kwon Doe ou en Jujitsu, on aura tendance à privilégié la rapidité d'execution et les résultats seront assez rapide. Pour utiliser des termes usuels : la courbe d'apprentissage n'est pas très raide, et on peut avoir des résultats imparfait dès le début. En revanche, en Karaté Shotokan, on aura tendance à privilégier un apprentissage long et arride à base de Kata, il suffit de regarder le karaté-kid (vieille version) pour comprendre qu'il y a plus trippant comme apprentissage des bases...

On comprends facilement la parallèle avec la programmation, les langages de scripting (Python, PHP, ...) se concentrant plus sur les résultats et l'execution, et les langages historiques comme Java/C++ étant plus orienté rigueur.

Mon point est le suivant, la puissance s'acquière rapidement à la fois en informatique et en arts martiaux, mais l'évolution et le travail fait qu'on lui substitue la maîtrise de notre art. Je m'explique : si on prends la programmation cette fois, au début on commence par le langage, seulement le langage, on avance et on s'habitue aux design patterns, on prends en main des architectures usuelles, des technologies afférentes, ensuite des méthodes de travails - des méthodes de tests.

Seulement pour un oeil non-averti qu'est ce qui va différencier un développeur sénior qui travaille en TDD - d'un junior "confirmé" qui a acquis la puissance mais pas la maîtrise. Très clairement le développeur sénior mettra plus longtemps, à specs équivalente, pour réaliser le travail, à cause du TDD, à cause de la rigueur et de la précision des gestes qu'il va chercher à atteindre. Vous allez me dire qu'en terme de qualité il n'y aura pas photos, très certainement. Mais un travail parfait sans bug n'existe pas en temps raisonnable et quelques tests basiques (réalisés par la QA) permettent souvent d'élaguer les erreurs usuelles.

La maîtrise, à terme, se substitue, souvent trop, à la puissance et à l'efficacité.

C'est peut-être là le rôle de ré-apprendre de nouveaux langages au fur et à mesure de son évolution, pour avoir non-seulement de nouveaux points de vue à explorer (chaque langage ayant son paradigme), mais aussi pour redécouvrir la puissance que l'on obtient au début en récompense d'avoir appris.

Sur ce,

Vale


Jun 8 2011

IncidentsRATP - IncidentsTransports est publié

Voilà c'est fait, après maintes péripéties et une attente longue je l'avoue, le projet est enfin publié en AGPL v3.

Le code est disponible ici : https://github.com/ssaboum/IncidentsTransports

Le projet est en Python utilisant Django, toute aide est bien sûr la bienvenue et la v2 se prépare tranquillement.

Enjoy !

Vale


May 31 2011

Etat de fait et fatalité

Un état de fait m'énerve, il m'énerve d'une part parce que dans d'autres domaines professionnels, il n'est pas aussi exacerbé, et d'autre part parce que je pense que la tendance s'accélère.

Pour résumer,

  • Un cuisiner peut devenir un chef qui se réinvente tout le temps, et fait de sa cuisine un art ;
  • Un architecte construit des edifices, et tire à chaque itération des leçons de ses erreurs ;
  • Un médecin diagnostique des maladies et construit les contre-mesures adaptées ;
  • Un manager analyse, planifie et anticipe les problèmes de son projet et de son équipe pour atteindre un objectif ;
  • Enfin, et ce pour les décideurs et l'opinion publique, un développeur ...  pisse du code.

Il pourrait être en Inde, en Thaïlande ou en région parisienne, ça ne change quasi rien, il lui suffit d'une tête (mal faite ou bien faite) d'un dossier de spec, d'un manager qui gueule, d'une QA (elle-même outsourcée) chargée de vérifier que ça correspond bien aux desiderata du client, et c'est tout !

Mais alors me direz-vous, "ce n'est pas le cas partout, quid des startups ? quid des méthodologies agiles ? quid du DevOps et du Software Craftsmanship !

Ben rien, en startup, j'en ai vu beaucoup qui considère les devs comme tout le monde, alors que pour moi (biaisé comme je suis) c'est eux qui créé le produit !

Et là on atteints mon favoris, les méthodologies Agiles, Scrum, Lean, Xp, Kanban etc... Quasi-toutes responsabilisantes pour les devs, mettant l'équipe au centre, facilitant leur travail etc... Eh bien désolé de vous décevoir, mais au delà des laboratoires de Toyota, on se retrouve dans le beau petit monde du Flicage ou le standup devient un reporting au manager, et où beaucoups de gourous et pratiquant (français) vous expliqueront bien gentiment que les développeurs sont des "gens simples"/ressources/abrutis qu'il faut savoir controller. Et qu'une fois leurs pouvoirs débloqués vous pourrez enfin bien vous faire voir de votre hierarchie !!

youhou... Sur ce

Vale


May 1 2011

Should i really learn Java ?

So i've been a professional Java developper for a few years now, and the question seems interesting to me. Should, let's say a student, really learn Java even if he does not want to do "Enterprise applications" ?

Short answer, Yes.

Long answer, you've got to know what Java is and what it's not, and i'm not talking about technical specs, but more about the place of Java in the world right now. Let's begin with what it's not, it's not :

  • what the cool kids do right now ! they do ruby, scala, clojure, even erlang (so cool...), but they don't do java unless they have to.
  • what the web is all about right now ! the web is about fast prototyping, agile development, continuous integration and deployment. Java is heavy, not designed for rapid prototyping and deployment is so painful that you need third party drug to ease the pain.
  • what you'll want to be doing for the rest of your life !
  • the best way to create distributed, scalable applications !
  • going to change anytime soon. It may be an advantage or a drawback, depending mainly on your age and goals.

However, Java is :

  • A de-facto standard, that you need to know !
  • running on the best VM out here !
  • the obvious language if you really really need a job ! So treasure it because it's just like Cobol, it's here to stay. You want it or not.
  • maybe the last non-Functionnal language you'll see in the coming years ! At least if we keep on creating languages to leverage the multi-core way.

Maybe i'm wrong, maybe it's all bullshit and i don't know what i'm talking about. Even is so, Learn Java, the hard way if you have to. Because even some of the coolest things out there (Mahoot, Hadoop, Lucene, Solr) are in Java, and Google's main language is still Java. Sur ce

Vale.


Apr 7 2011

Crypto - Vigenère

Je me remet au point niveau sécurité, alors même si j'apprécie beaucoup reprendre les bases de sécurité web, on va commencer par de la cryptographie, histoire de limiter les trucs *****.

Donc le but de ces petits exercices, c'est plus de se souvenir de certains cryptages et de prendre des reflexes pour les reconnaître et les casser. On commence par un Vigenère, je laisse le soin à Wikipedia de vous en rappeler les termes, comment le cryptanalyser ?

Outre le fait qu'on peut penser à un chiffre de Vigenère quand certaines lettres et ponctuations reviennent souvent, la cryptanalyse de ce chiffrement utilise le test de Kasiski et si vous n'avez pas l'envie de ré-implémenter ce crack Simon Liu a codé en Python un utilitaire pour cracker ce chiffrement, et l'appli web est disponible ici : Automatic Vigenere Decoder/Solver.

Si j'ai un peu de temps, j'en ferais un semblable en améliorant un peu son code qui est déjà très compéhensible.

Vale


Mar 28 2011

TOR et HADOPI

Juste pour faire un petit point autour de la HADOPI et plus précisément de la position de la HADOPI envers les proxy, et plus spécifiquement de la distribution des proxy comme le fait TOR.

La HADOPI n'empêche en rien l'utilisation de proxy, en somme l'utilisation de TOR ou d'un quelque autre proxy pour se connecter à internet (et donc utiliser une adresse IP différente de la sienne) n'est pas interdite. Le réseau TOR étant conçu par couche de proxy, il est difficile et à ma connaissance pour l'instant impossible d'arriver à remonter au client initial, donc de ce coté là notre anonymat est respecté.

En revanche si vous utilisez TOR comme serveur, et que vous devenez vous-même un proxy, un maillon de la chaîne, vous n'êtes toujours pas hors la loi, mais un risque apparaît. En effet si vous êtes le noeud final (la passerelle apparente) d'une personne qui va télécharger illégalement des oeuvres protégées, votre responsabilité devient engagé au titre de la clause "d'obligation de sécurisation de sa connection internet".

Pour résumé l'utilisation de TOR est autorisée (encore heureux), mais si vous devenez un noeuds du réseau ou plus précisément si vous devenez à un moment le noeud final de connection d'une personne, alors votre responsabilité devient engagée et vous risquez de vous prendre une lettre. Une proposition a été faite que seuls les pays "libre" devraient être des noeuds finaux sur le réseau, je pense que si on continue dans cette direction, il y a peut de chance qu'on reste dans cette liste.

Vale


Mar 25 2011

How to be a happy programmer (with Python) ? 2/3

In the series of the Python "features" that makes me happy last time i began with two concepts, the with statement and the list comprehensions, now i'm going to talk about Multiple assignments and the import aliases.
  • Multiple assignments

It's a simple idea that lets you return a series of value and on the other end assign those multiple values at the same time, example when you're splitting a string or extracting groups from a regular expression :

  1. >>> split_me ="here,we, are,again"
  2. # splitting we'll get a list of values
  3. >>> split_me.split(",")
  4. ['here', 'we', ' are', 'again']
  5. # if you don't know the number of values you're going to have
  6. # you can't use this features, example :
  7. >>> (start,end) = split_me.split(",")
  8. Traceback (most recent call last):
  9.   File "", line 1, in
  10. ValueError: too many values to unpack
  11. # but if you know that there's going to be n values :
  12. >>> (start,end) = split_me.split(" ")
  13. >>> start
  14. 'here,we,'
  15. >>> end
  16. 'are,again'
  • Import aliases

It means what it says, when you import a library or module, you can use aliases, example in Django for shortcuts :

  1. # this is extracted from my own code :
  2. from django.http import HttpResponse, HttpResponseRedirect as redirect
  3. from django.shortcuts import render_to_response as render
I won't start to talk about the standard library as a whole, or libs like Numpy, Scypy, scikit-learn, .... that makes it so easy to just think in Python.
And you ? What are the Python constructs (2.x or 3.x) that makes you feel happy and efficient at the end of the day ?

Mar 25 2011

Using TOR with Python

There are many occasion where you may be limited using your own IP address, i will obviously only refer myself to "rightful" cases where you need to use different IP address in very short lapse of time. Let's say you want to test your website localization functionality, or just access it using many different IP address and see how the system deals with it.

TOR is a wonderful tool for that. TOR (The Onion Ring to be specific) is a tool that allows you to use several IP addresses as gateways to connect to the Internet and change the path you use dynamically. It's main goal is to help you "Protect your privacy and defend yourself against network surveillance and traffic analysis.". I used it a long time ago, when connections were so bad, that using it was mostly a burden and not very practical.

But recently when i had to span HTTP requests through several IP address, i got frustrated by two facts :

  • First : i didn't have enough servers available to do it, and buying them from Amazon EC2 is not a solution as those servers may have the same IP address and all accounts are limited to 5 Elastic IP addresses and i don't want to buy myself for 400$ worth of servers i may use only 1 hour !
  • Second : i need to build a complex distributed environment (like a MapReduce job) and .... well i don't want to, i don't need parallel tasks, i just need a varying exit point.

So after a frustrating night of coding, i found myself thinking back of TOR. I installed it back again with Vidalia, and it worked ! Using Vidalia i could change my IP address when i needed and re-execute my tests with a brand new IP address. Of course it wasn't perfect as i was using sometimes 5 different relay points before reaching my goal but as i was not downloading anything heavy, it went well. But still, i had to change by hand my IP address. So the real point of this article is : " how to change dynamically your IP address using Python and TOR ?"

So first you need TOR installed, you can get it here : https://www.torproject.org/download/download.html.en and activate the remote control here  :

Then i'm going to assume you have Python, Git and Pip installed. To be clear on the principles of all this, TOR offers a relatively complex control system that you can connect to using Telnet, you can see the full command list and a few examples on the TOR website and here : http://thesprawl.org/memdump/?entry=8 . I'm going to refer only to the command i want to use : "re-new my route".

So to install TorCtl, the library we will want to use to control TOR, we'll clone the Git repository of the project, and install the library using Pip (it's pure laziness, i admit, because using python setup.py install works just fine too) :

  1. $ git clone git://github.com/aaronsw/pytorctl.git
  2. Cloning into pytorctl...
  3. remote: Counting objects: 555, done.
  4. remote: Compressing objects: 100% (180/180), done.
  5. remote: Total 555 (delta 376), reused 552 (delta 375)
  6. Receiving objects: 100% (555/555), 145.62 KiB | 213 KiB/s, done.
  7. Resolving deltas: 100% (376/376), done.
  8. $ pip install pytorctl/
  9. Unpacking ./pytorctl
  10.   Running setup.py egg_info for package from [...]
  11. Installing collected packages: torctl
  12.   Running setup.py install for torctl
  13. Successfully installed torctl
  14. Cleaning up...

So now if Tor is running and you try to do this :

  1. $ python
  2. Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49)
  3. [GCC 4.2.1 (Apple Inc. build 5646)] on darwin
  4. Type "help", "copyright", "credits" or "license" for more information.
  5. >>> from TorCtl import TorCtl
  6. >>> connection = TorCtl.connect(passphrase="lol")
  7. >>> connection.is_live()
  8. True

It's proof that it works, just use close() on the connection object to disconnect yourself. Now all we need to do is use this connection to send signals to TOR and tell urllib2 to use this precise connection, let's go :

  1. import urllib2
  2. # using TOR !
  3. proxy_support = urllib2.ProxyHandler({"http" : "127.0.0.1:8118"} )
  4. opener = urllib2.build_opener(proxy_support)
  5. urllib2.install_opener(opener)
  6. # every urlopen connection will then use the TOR proxy like this one :
  7. urllib2.urlopen('http://www.google.fr').read()
  8. # and to renew my route when i need to change the IP :
  9. print "Renewing tor route wait a bit for 5 seconds"
  10. from TorCtl import TorCtl
  11. conn = TorCtl.connect(passphrase="lol")
  12. conn.sendAndRecv('signal newnym\r\n')
  13. conn.close()
  14. import time
  15. time.sleep(5)
  16. print "renewed"

Now you know everything i know. On the receiving end, i don't think there's that much data on how to identify the "source" of the request, if you've got any clue about that, tell me in the comments.

Vale