Ouvrir la navigation secondaire

Ce billet a plus de deux ans. S'il contient des informations techniques elles sont peut être obsolètes.

Précédent The hash-bang theory
Suivant L'échec des propriétés CSS expérimentales

django-tweets-lab

Il y a quelques temps j'ai commencé à sauvegarder mes tweets sur mon site par l'intermédiaire d'une application Django.

Au fil du temps j'y ai greffé des fonctionnalités sympa et vu qu'il y a maintenant un peu de matière j'ai décidé de pousser le code dans le seau à bits. Ça donne django-tweets-lab. Je pense qu'on peut faire pas mal de choses sur la base de cette appli :)

Voici quelques notes à son propos.

Tout le monde les préfère tiny

J'ai déjà écrit sur le sujet : je n'aime pas la réduction d'URL, il n'y a aucune raison valable de faire ça sinon la limitation en termes de nombre de caractères imposée par Twitter. Or en inspectant mes tweets j'en ai décompté plus de 500 utilisant bit.ly ! Probablement la faute d'un client zélé :D

Blague à part, utiliser l'outil c'est accepter les règles et les limitations. Par contre, pas de raison de vouloir conserver les URLs en format réduit chez soi. J'ai donc ajouté un résolveur d'URL réduites et je me suis beaucoup inspiré de Shortening and Expanding URLs with Python. Du coup une petite boucle for dans un manage.py shell et le tour est joué.

Sinon à part ça je n'ai pas de griefs contre bit.ly qui utilise beaucoup Python :) Il y a parfois des billets intéressants chez leurs Pythonistas : Handling Internationalized Domain Names (IDN) in Python.

Script autonome

Il faudra récupérer vos tweets périodiquement, tous les jours par exemple, probablement plus souvent si vous êtes du genre flooder. Pour ce faire j'ai mis en place un script exécuté automatiquement via cron.

Pour récupérer ses tweets : un GET statuses/user_timeline en spécifiant un format JSON à l'API de Twitter est suffisant dans le cas d'un compte public.

Avantages :

  • cette méthode ne requiert pas d'authentification OAuth
  • il y a pas mal de paramètres (include_rts etc.)
  • la méthode permet de récupérer jusqu'à 3200 tweets d'après la doc, l'exercice de sauvegarder l'ensemble de ses tweets est laissé au lecteur
  • un simple json.load permet de désérialiser en objet Python

Toute la difficulté d'utiliser un script autonome dans une application Django est de pouvoir lui dire quelle configuration utiliser, à quelle base de donnée se connecter, quel PYTHONPATH utiliser etc. De nombreuses solutions ont émergées mais la plus élégante fut l'introduction des custom django-admin commands. Il suffit d'écrire la commande et de créer le cron job qui déclenche le manage.py de ladite commande avec éventuellement le chemin de l'exécutable Python d'un virtualenv.

L'autre avantage des commandes personnalisées est de pouvoir utiliser les entrées-sorties pour debugger et tester le code :

out = StringIO()
call_command('updatetweets', stdout=out)
self.assertTrue(
    'Successfully backuped' in out.getvalue().strip())

heapq.nlargest

Avec l'ensemble des tweets à portée de clavier ça devient la fête du slip. Vous pouvez faire un peu de data mining pour votre compte personnel, ça changera pour une fois :p Rien de bien méchant, juste compter les mots les plus utilisés par exemple. Ca se fait très facilement en stockant un hash des mots et de leur nombre d'occurrences dans un tableau.

Ensuite il reste à trier et récupérer les mots les plus utilisés. La fabuleuse librairie standard Python permet de faire ça très facilement via heapq.nlargest par exemple.

JavaScript côté client

Un index JSON de tous les tweets est généré par l'application le cas échéant. L'URL de cet index est stockée dans un attribut data d'un élément HTML input. Il est ensuite chargé par le code JavaScript, puis parsé avec JSONQuery pour le fun et le profit :)

Le code côté client est une partie importante de l'application permettant d'interagir en direct avec l'index des tweets sans fracasser la DB. Pour l'instant je suis assez étonné de la rapidité de JSONQuery sur un index qui aujourd'hui pèse déjà 434 ko pour 4238 tweets.

Évolutions

Du coup en réfléchissant je me demandais si ça n'était pas un cas d'utilisation pour tester CouchDB ? C'est une piste d'évolution probable.

C'est la même chose pour pushState et replaceState côté client. J'avais commencé à jouer avec mais c'est encore un peu jeune. J'ai pas réussi à faire rapidement ce que je voulais de façon cross-modern-browsers et ça m'a vite saoulé :)

Quoiqu'il en soit, si vous voulez utiliser cette application ou la modifier pour vos besoins, n'oubliez pas de bien paramétrer toute votre chaîne pour parler UTF-8 d'un bout à l'autre :)