Humus numericus

Aller au contenu | Aller au menu | Aller à la recherche

R, Spip et autres

lundi 12 juillet 2010

Updated tangotango emacs color theme

EDIT : This post is now quite deprecated. Installation instructions and new versions are posted on the github project page.

I just updated my original ”tangotango” emacs color theme, based on the tango palette colors. I’ve tweaked some details and moved the source code to github. Here are updated installation instructions and screenshots :

Installation instructions

  1. Download and install the color-theme emacs package either via your linux distribution or via the source tarball
  2. Download and install color-theme-tangotango.el from github
  3. Make sure that both color-theme.el and color-theme-tangotango.el are in your load path

There are several ways to load the tangotango color theme from your .emacs, as documented on emacswiki. The way I currently use should work for a daemonized emacs and allows the selection of different themes for GUI or console based frames :

(require 'color-theme)
(setq color-theme-load-all-themes nil)

(require 'color-theme-tangotango)

;; select theme - first list element is for windowing system, second is for console/terminal
;; Source : http://www.emacswiki.org/emacs/ColorTheme#toc9
(setq color-theme-choices 
      '(color-theme-tangotango color-theme-tangotango))

;; default-start
(funcall (lambda (cols)
    	   (let ((color-theme-is-global nil))
    	     (eval 
    	      (append '(if (window-system))
    		      (mapcar (lambda (x) (cons x nil)) 
    			      cols)))))
    	 color-theme-choices)

;; test for each additional frame or console
(require 'cl)
(fset 'test-win-sys 
      (funcall (lambda (cols)
    		 (lexical-let ((cols cols))
    		   (lambda (frame)
    		     (let ((color-theme-is-global nil))
		       ;; must be current for local ctheme
		       (select-frame frame)
		       ;; test winsystem
		       (eval 
			(append '(if (window-system frame)) 
				(mapcar (lambda (x) (cons x nil)) 
					cols)))))))
    	       color-theme-choices ))
;; hook on after-make-frame-functions
(add-hook 'after-make-frame-functions 'test-win-sys)

(color-theme-tangotango)

Note that I also had to add a (color-theme-tangotango) line at the end of my .gnus file in order to apply the color theme to Gnus.

Screenshots

Here is a screenshot of the color theme with an emacs-lisp file :

tangotango_elisp.png

One with a Gnus summary and article buffers :

tangotango_gnus.png

And one with an org-mode buffer :

tangotango_org.png

mercredi 12 mai 2010

La domination adulte

Ce texte a également été publié sur le site Les mots sont importants.

Une domination cachée

Une domination sociale n’est jamais aussi efficace que lorsqu’elle nous apparaît comme «naturelle» et demeure en grande partie invisible. Les multiples rapports de domination qui structurent notre vie sociale sont visibles à des degrés divers : certains sont connus et reconnus (la domination masculine par exemple), d’autres ont été mis en évidence mais restent en partie cachés (on pourra citer la domination culturelle et symbolique). On sait aussi que mettre au jour un rapport de domination ne suffit en rien à le faire disparaître, mais c’est pourtant une étape nécessaire : il faut prendre conscience de quelque chose pour pouvoir commencer à lutter contre.

Or il existe au moins un type de domination qui reste aujourd’hui presque totalement invisible, que nous côtoyons pourtant tous les jours, et pour lequel nous avons tous été à la fois dominé et dominant : il s’agit de la domination exercée par les adultes sur les enfants.

Énoncer qu’il existe un rapport de domination des adultes sur les enfants peut sembler à la fois une évidence et une absurdité : une évidence, car on ne saurait nier que la position d’adulte confère globalement une position d’autorité sur celle d’enfant ; une absurdité, car cette position nous apparaît comme normale, naturelle et même positive. Elle s’appuie de plus sur des caractéristiques «objectives» : les enfants sont objectivement «dépendants», «fragiles», ce sont des «êtres en cours de formation» qu’il convient donc de «protéger», «d’éduquer», «d’encadrer», etc.

Il existe pourtant des signes clairs qui permettent de montrer que ce rapport adulte/enfant est bien un rapport de domination, qui plus est particulièrement violent.

Le statut inférieur accordé aux enfants est d’abord présent dans la manière de les nommer. L’enfant, étymologiquement, est celui «qui ne parle pas». Il appartient au monde des «petits». Jusqu’à l’âge de sa majorité, il est considéré comme un être «mineur». Par ailleurs, la plupart des appellations utilisées pour le désigner sont de l’ordre du péjoratif : gosse, gamin, morveux, chiard… Et celles-ci sont souvent considérées comme des insultes quand elles sont appliquées à des adolescents ou des adultes («bébé», «gamin», «ne fais pas l’enfant», etc.) [1].

Objectivement, l’enfant est évidemment dans une situation de dépendance quasi totale vis-à-vis des adultes, et en particulier de ses parents : pas de ressources propres, pas d’indépendance possible, pas de droit de regard sur les décisions le concernant, y compris jusqu’à un âge avancé. Une fois scolarisé il est soumis à des horaires et à une charge de travail très importants, comparables à ceux endurés par beaucoup d’adultes dans leur vie professionnelle. En-dehors de l’école il n’est jamais totalement maître de son temps et de ses activités car c’est en général toujours l’organisation et la volonté des adultes qui l’emportent («on doit partir, tu joueras plus tard»).

Typique de nombre de relations de domination, cette dépendance est d’ailleurs totalement «renversée» dans certains discours : on parle ainsi «d’enfant-roi» ou «d’enfant-tyran», tout comme on insinue parfois que les chômeurs sont des privilégiés ou que les immigrés sont coupables de racisme anti-français.

Une vision profondément négative de l’enfant

Les enfants bénéficient parfois d’une valorisation sur des aspects secondaires et limités, en général basée sur des attributs physiques ou des comportements conformes aux attentes : on les jugera «mignons», «adorables», «gentils», «polis», «bien élevés». Mais ces valorisations temporaires masquent en réalité une vision extraordinairement négative de l’enfant, et ce dès sa naissance. Dans la plupart des discours (médicaux, éducatifs, psychologiques), l’enfant est considéré comme un être qui va «chercher la faille», «tester les limites», et qui, si on ne lui impose pas un cadre contraignant, va «en profiter», accumulera les bêtises et les comportements égoïstes. Héritage d’une tradition judéo-chrétienne et psychanalytique [2], cette vision fait croire à un enfant porteur de «vices» ou de «pulsions», qu’il va falloir redresser et corriger par le biais d’une éducation rigoureuse. Ainsi, dès les premiers instants, le bébé qui pleure sera accusé de «comédie» et de tentative de manipulation auxquelles il ne faut pas céder, sous peine d’être par la suite totalement débordé et, à la limite, transformé en esclave de son propre enfant.

On trouverait sans doute là de nombreux parallèles avec d’autres formes de domination : on pourra citer les femmes, souvent réduites à leurs attributs physiques, et dont l’image reste souvent très négative (historiquement comme sources de péchés ou de tentations, aujourd’hui encore comme susceptibles de séduction, de manipulation ou de «bêtises» comme des dépenses excessives et futiles, etc.) ou les classes populaires, parfois valorisées pour divers attributs secondaires (le franc-parler, la convivialité, la force de travail…) mais fondamentalement extrêmement stigmatisées et implicitement soupçonnées de propension à la violence ou au racisme [3]. Une domination a en effet toutes les chances de paraître légitime si elle fait passer le groupe dominé comme potentiellement «dangereux».

La position dominée des enfants s’exprime aussi à travers la non prise en compte, voire la négation de leur parole et des besoins qu’ils peuvent exprimer. Bien souvent ces besoins ou envies sont considérés comme des «caprices», donc comme des demandes qui n’ont pas de valeurs en elles-mêmes. Un enfant qui a très envie d’une console de jeux se verra souvent accusé de «caprice». Un adulte souhaitant acheter un /iPhone/, beaucoup moins (encore que cette probabilité augmentera fortement s’il s’agit d’une femme).

Cette notion centrale de «caprice» commence d’ailleurs très tôt, y compris pour l’expression de besoins extrêmement fondamentaux (la faim, le besoin de contact ou d’attention) par les nouveaux-nés. Et elle concerne également la négation du chagrin ou de la douleur : la plupart du temps, lorsqu’un enfant tombe et se fait mal, les premiers mots prononcés sont «ce n’est rien, ne pleure pas». On se souviendra d’ailleurs que jusqu’à récemment les bébés étaient opérés sans anesthésie.

Enfin, la domination adulte s’exprime le plus brutalement par la maltraitance dont les enfants sont souvent les objets. Au delà des cas extrêmes (les victimes de viols ou de meurtres «passionnels» liés à des séparations sont presque exclusivement des femmes ou des enfants), les enfants demeurent le seul groupe social qu’on a légalement le droit de frapper [4]. On accepte encore aujourd’hui que les enfants soient battus, pour leur bien, comme on acceptait hier que les femmes soient battues, pour les mêmes raisons.

Et cela sans parler des violences psychologiques : insultes, cris, punitions, humiliations, qui sont monnaie courante à des degrés divers et le plus souvent parfaitement tolérées.

Une domination centrale

Tenter de faire apparaître la relation adulte/enfant comme un rapport de domination comporte une double difficulté : chaque argument peut apparaître soit comme une évidence, soit être immédiatement réfuté, y compris par soi-même, par l’idée que cet état de fait est peut-être regrettable ou excessif, mais qu’il est nécessaire, sous peine de conséquences négatives.

L’autre difficulté est qu’en tant qu’adulte, et encore plus en tant que parents, nous devons prendre conscience de cette domination en étant nous-mêmes dominants. Ceci passe alors par une remise en cause personnelle et un travail permanent pour ne pas se laisser aller à ce qu’on ferait souvent naturellement : se comporter avec ses enfants d’une manière qu’on n’accepterait pas de la part d’un homme envers une femme ou d’un patron envers ses employés.

Pourtant cette domination est une question particulièrement cruciale : nous l’avons tous vécue en tant que dominés étant enfants. Nous avons tous subis nombre de violences plus ou moins grandes, nous les avons acceptées et elles nous apparaissent bien souvent, en tant qu’adulte, comme nécessaires et positives. Or cette expérience et cette acceptation de la domination jouent certainement un rôle dans sa reproduction plus tard en tant qu’adulte, mais aussi dans son application à d’autres contextes et vis-à-vis d’autres groupes sociaux.

Sur le plan politique, enfin, tout ou presque reste à faire. En effet, à la différence d’autres types de dominations qui, à défaut d’être réellement combattues, ont au moins acquis une certaine visibilité (domination masculine, domination de classe, domination hétérosexuelle…), la domination adulte et la place des enfants sont des thématiques totalement absentes du champ politique. Les enfants ne sont présents, y compris dans les programmes de gauche, que par le prisme de l’école, de la santé ou des modes de garde. Avec une difficulté supplémentaire : si le plus souvent les dominés peuvent mener eux-mêmes le combat contre leur domination, dans le cas des enfants c’est presque impossible…

Au-delà des luttes pour les «droits de l’enfant» ou la «protection de l’enfance», qui visent en général à s’attaquer aux violences les plus flagrantes, un véritable travail de mise à jour et de construction politique est donc nécessaire si on souhaite aboutir progressivement à la fin des violences et à une égalité de considération et de traitement entre adultes et enfants.

Notes

[1] Pour une analyse plus détaillée on pourra se reporter au texte L’enfance comme catégorie sociale dominée.

[2] Pour analyse historique détaillée de la genèse de cette conception négative de l’enfant, voir l’ouvrage d’Olivier Maurel, Oui, la nature humaine est bonne !, Robert Laffont, 2009.

[3] Cf. la désormais célèbre citation de Nicolas Baverez : «Pour les couches les plus modestes, le temps libre, c’est l’alcoolisme, le développement de la violence, la délinquance».

[4] Sur la question de la violence physique sur les enfants et de son interdiction, voir le travail de l’Observatoire de la violence éducative ordinaire.

lundi 26 avril 2010

Traduction française de l'Appel pour une Internationale socialiste participative

Mise à jour 08/09/2010 : la traduction française, avec quelques corrections suite à des relectures par rapport à la version présentée ici, est désormais en ligne sur la page officielle de l’appel.

Peut-être n’avez-vous pas entendu parler de l’appel pour une Internationale socialiste participative, initiative lancée par le site Z Communications. ZCom et ses dérivés (ZNet, ZMag, ZSpace…) est un site assez étroitement lié à des mouvements libertaires nord-américains dans la mouvance de Noam Chomsky ou de Michael Albert (l’auteur du très intéressant Après le capitalisme.

Le but de l’appel est d’initier une réflexion et éventuellement un mouvement pour la constitution d’une nouvelle Internationale dont l’objectif serait d’aider à coordonner au niveau mondial des organisations, associations, projets partageant un certain nombre de valeurs et d’objectifs, en gros la lutte contre toutes les formes non fondées de pouvoir ou de domination (ce qui comprend les dominations liées à la classe sociale, au genre, à l’âge, à l’orientation sexuelle, à l’origine, à la religion, etc.).

Cet appel constitue un premier pas, une manière de se compter et d’initier, peut-être un semblant de quelque chose à partir des personnes qui ont indiqué le soutenir (un peu moins de 2000 à l’heure où j’écris).

Je viens de tenter de traduire le texte en français afin de le rendre un peu plus accessible. Comme ça n’est pas forcément une tréaduction aisée, en tous cas qui pose pas mal de questions sur des subtilités sémantiques ou des notions relativement spécifique au contexte anglo-saxon, je serais très preneur de relectures et de remarques éventuelles. Donc n’hésitez pas ! :-)

Voici le texte de la traduction :

Nous, soussignés, approuvons et soutenons l’idée d’une nouvelle Internationale et préconisons que sa création comporte l’évaluation, l’approfondissement, l’amélioration et enfin la mise en oeuvre, parmi la liste de points suivants, de l’ensemble de ceux que les participants à l’Internationale auront ensemble jugé utiles et nécessaires :

1. Une nouvelle Internationale devrait en priorité s’occuper, au minimum, des questions suivantes :

  • la production économique, la consommation, et la répartition, ce qui inclut les relations entre classes sociales
  • les relations familiales, la socialisation, le travail domestique et la procréation, ce qui inclut les questions de genre, de sexualité et d’âge
  • les relations entre communautés culturelles, ce qui inclut les questions de «race», de nationalité et de religion
  • le pouvoir et la politique, ce qui inclut les questions du droit et des législations
  • les relations internationales, ce qui inclut l’entraide, les échanges, et l’immigration
  • l’écologie, ce qui inclut les relations avec notre environnement naturel et les autres espèces

La nouvelle Internationale doit aborder l’ensemble de ces questions sans en considérer certaines plus importantes que d’autres, puisque (a) elles auront toutes un effet décisif sur les caractéristiques d’une nouvelle société, (b) omettre l’une d’entre elles pourrait anéantir les efforts pour créer une nouvelle société, et (c) les groupes les plus directement concernés seraient durement exclus si les questions qui les touchent étaient considérées comme d’importance secondaire.

2. Notre vision d’un avenir socialiste participatif inclut, au minimum, les objectifs suivants :

  • la production économique, le consommation et la répartition des richesses doit aboutir à une société sans classes, ce qui inclut un accès équitable pour tous à une éducation de qualité, à la sécurité sociale, à la nourriture, à l’eau, à la santé, au logement, à un travail digne et porteur de sens, et aux outils et conditions permettant l’épanouissement personnel
  • les relations familiales, les rapports de genre et la sexualité ne doivent privilégier aucun groupe par rapport à un autre et ce quels que soient l’âge, le genre ou l’orientation sexuelle, ce qui inclut la fin de toute forme d’oppressions envers les femmes tout en garantissant l’attention nécessaire aux enfants, l’accès aux soins médicaux et aux loisirs, etc.
  • les relations entre communautés culturelles, ethniques ou religieuses doivent protéger les droits et l’identité de chacune d’entre elles tout en garantissant un respect mutuel, ce qui inclut la fin de toutes les structures racistes, ethnocentriques ou sectaires, tout en assurant simultanément la prospérité et les droits des peuples indigènes
  • la prise de décision politique, le règlement des conflits et la mise en oeuvre de projets collectifs doit donner «le pouvoir au peuple» sans qu’aucun groupe ou communauté ne soit privilégié, ce qui inclut une participation égale et la justice pour tous
  • le commerce, les communications et autres modalités d’échanges internationaux doivent aboutir à la paix et à la justice tout en éliminant tous les vestiges du colonialisme et de l’impérialisme, ce qui inclut l’annulation de la dette des pays du Sud et la reconstruction de règles et de relations internationales pour aller vers une communauté de nations équitable et juste
  • les choix écologiques doivent être non seulement viables, mais aussi prendre soin de l’environnement en accord avec nos plus hautes aspirations pour nous-mêmes et pour notre planète, ce qui inclut une réelle justice face aux évolutions climatique et une recherche de l’innovation dans le domaine de l’énergie

3. Les principes et valeurs qui guident les débats internes à l’Internationale en termes de programme et de stratégie doivent s’appuyer au minimum sur les valeurs fondamentales suivantes. Ceci implique notamment que la structure de l’organisation doit être pensée pour incarner au mieux ces valeurs dès à présent :

  • la solidarité, pour aider à la coordination, l’aide mutuelle et le succès collectif de mouvements et projets partout dans le monde
  • la diversité, pour encourager l’innovation et la créativité, respecter les différences d’opinion, et reconnaître que certaines idées minoritaires pouvant paraître déplacées ou inapplicables aujourd’hui peuvent s’avérer avant-gardistes demain
  • l’équité, pour aboutir à une répartition juste des revenus et de la richesse
  • la paix et la justice, pour garantir l’équité entre nations et des relations internationales constructives
  • une écologie viable et respectueuse, pour garantir la survie de notre espèce et améliorer les interactions avec notre milieu et les autres espèces
  • s’inspirer des concepts de «démocratie», de «pouvoir au peuple», de «démocratie participative» et d’«autogestion», pour permettre une participation et une influence équitables pour tous dans les prises de décision

4. Une Internationale doit être plus que la simple somme de ses membres, et doit rejeter l’idée d’une seule ligne de pensée qui résumerait tous les points de vue en un modèle unique. Pour cela elle doit :

  • inclure et approuver des «courants» en tant que porteurs de points de vue différents, pour éviter le sectarisme et aider au développement de l’organisation
  • établir que chaque courant doit respecter les intentions des autres courants, à partir du moment où celles-ci sont des intentions de fond (politiques et idéologiques) et n’ont pas d’autres motivations ; mener des débats de fond qui constituent un élément important du projet global
  • offrir à chaque courant les moyens de débattre ouvertement avec les autres courants pour essayer de faire émerger de nouvelles idées politiques et de nouveaux programmes
  • garantir que temps qu’un courant accepte les principes de base de l’Internationale et opère en accord avec ses règles et ses méthodes, ses positions minoritaires auront l’espace nécessaire non seulement pour s’exprimer mais aussi pour continuer à développer ses point de vue afin de prouver leur valeur ou, au contraire, de découvrir leur inadéquation

5. Les membres de la nouvelle Internationale pourront être des partis politiques, mouvements, organisations, ou même des projets, selon les règles suivantes :

  • les membres, employés et personnels de chaque organisation membre de l’Internationale deviendraient à leur tour membres de l’Internationale
  • les individus souhaitant rejoindre l’Internationale devraient obligatoirement le faire en rejoignant une des organisations membres
  • chaque organisation membre maintiendrait son propre agenda pour ses activités et l’Internationale n’aurait aucun droit de regard sur ce dernier
  • dans le même temps, chaque organisation membre serait fortement incitée à coordonner ses activités avec les normes, pratiques et agendas de l’Internationale, afin de mettre en oeuvre solidarité et autonomie
  • les organisations membres seraient de tailles variées, mais puisque les décisions de l’Internationale ne contraignent pas les organisations membres en dehors de l’agenda collectif de l’Internationale, un processus de prise de décision adéquat pourrait être le suivant : discussions et explorations approfondies ; sondages informels auprès de l’ensemble des membres pour évaluer les différentes tendances ; améliorations et nouvelles propositions pour obtenir un soutien plus large ; vote final des organisations membres.

6. Les actions et activités choisies par une nouvelle Internationale seront évidemment fonction du contexte et de la volonté des ses membres. On peut cependant citer à titre d’exemple :

  • une nouvelle Internationale pourrait appeler à des évenements internationaux et à des journées de protestation, pour soutenir des luttes menées par des organisations membres, pour aider ces organisations face à la répression, pour s’impliquer dans des débats et faire avancer compréhension et savoirs mutuels
  • de manière plus ambitieuse, une Internationale pourrait aussi s’engager, par exemple, dans une campagne internationale massive concernant l’immigration, pour mettre fin à une guerre, pour réduire la durée de travail hebdomadaire au niveau mondial, ou pour éviter une catastrophe climatique, entre autre possibilités. Elle pourrait préparer du matériel, s’impliquer dans des campagnes d’éducation et de sensibilisation, mener des actions, inciter à des boycotts, soutenir des initiatives locales, etc.
  • il appartiendrait à chaque organisation membre de décider comment elle se positionne par rapport au programme général de l’Internationale, cependant il y aurait une incitation collective forte pour que chaque organisation membre participe et contribue du mieux qu’elle peut dans des campagnes et projets collectifs. Une des raisons d’être évidentes d’une Internationale est en effet d’aider les organisations, mouvements et projets de par le monde à sortir de l’isolement en prenant part à un processus plus large abordant des thématiques multiples avec la volonté de mettre en oeuvre collectivement des actions et des efforts partagés.

lundi 8 mars 2010

Comment protéger une adresse mail destinée à un enfant ?

L’autre jour ma fille de six ans et demi a eu envie que je lui installe un client mail sur son interface sur notre ordi familial. J’ai trouvé que c’était une bonne idée, mais je ne voulais évidemment pas utiliser une adresse ouverte à tous les vents, avec risque notamment de recevoir des spams inappropriés. La cahier des charges était donc le suivant :

  • que les deux parents reçoivent systématiquement une copie des messages reçus sur la boîte ;
  • que les messages reçus sur la boîte mail ne soient diffusés qu’après validation manuelle de la part d’un des deux parents ;
  • ajouter la possibilité de “whitelister” certaines adresses d’expédition pour ne pas avoir à valider systématiquement les messages qui en proviennent

Oui, bon, je sais, ça fait un peu big brother, mais vu le type de spam qu’on reçoit parfois, y compris sur des adresses a priori totalement privées, je préfère bétonner un maximum pour l’instant.

Je me suis demandé comment faire ça avec Postfix, Procmail ou je ne sais quel assemblage d’applications que j’utilise pour le mail, et puis j’ai finalement trouvé une solution que je trouve pas trop compliquée, et qui passe par la création d’une liste de diffusion, ici avec Mailman.

Donc voici la marche à suivre :

  1. Créer une liste de diffusion nommée prenom@domaine.org (l’adresse mail publique attribuée à l’enfant)
  2. Mettre les mails des parents comme administrateurs de la liste
  3. La configurer pour que tous les envois soient modérés par défaut, avec validation manuelle des administrateurs de la liste
  4. Créer une adresse mail “de transit” du type mail.prenom@domaine.org
  5. Abonner à la liste prenom@domaine.org les deux parents, ainsi que mail.prenom@domaine.org
  6. Configurer le client mail sur l’ordi familial pour aller lire les mails sur la boîte mail.prenom@domaine.org, tout en envoyant les mails avec l’adresse prenom@domaine.org

Et voilou ! À partir de là, chaque message envoyé à prenom@domaine.org passe par une phase de modération, et les deux parents reçoivent un mail avec un lien leur permettant de rejeter ou valider le message, et en plus la possibilité de placer l’expéditeur sur liste blanche (ou liste noire) pour éviter les validations ultérieures. Une fois le message validé, il est ensuite transféré de manière transparente sur la boite mail.prenom@domaine.org (donc à l’enfant) et sur les boîtes des parents.

Voilà, je ne sais pas si c’est très clair, mais ça a le mérite de fonctionner en tous cas :-)

Comment révoquer une clé PGP

Je viens de révoquer une clé PGP avec GnuPG pour une ancienne adresse mail. Voici la marche à suivre.

D’abord il faut noter l’identifiant de la clé publique que l’on souhaite révoquer. Pour cela on fait un :

$ gpg --list-keys

Et on note l’identifiant (8 caractères hexadécimaux du type A1B2C3D4). Ensuite on génère un certificat de révocation qu’on stocke dans un fichier :

$ gpg --gen-revoke A1B2C3D4 > revoke.txt

Puis on importe ce certificat de révocation :

$ gpg --import revoke.txt

On exporte la clé publique désormais révoquée :

$ gpg --export -a A1B2C3D4

On peut alors uploader la sortie de cette dernière commande sur un serveur de clé type pgp.mit.edu et d’ici peu, le monde entier sera informé que votre clé ne doit plus être utilisée.

mercredi 10 février 2010

Don't put a dot in your cronjobs names !

So you just setup a wonderful new cron job on your server that will make your life easier and your family happy. You put it in your /etc/cron.d in a file called wonderfulcronjob.sh but… your job is never launched.

You checked the permissions, the crontab syntax, ran the script manually, evertything is fine. You checked your syslog, but nothing is reported on it, not even the fact that the job is started. What’s the problem ?

The answer is in the run-parts manual page :

If the —lsbsysinit option is not given then the names must consist entirely of upper and lower case letters, digits, underscores, and hyphens.

So if you put a dot in your cron job name, it will not be run at all. Rename it to wonderfulcronjob-sh or just wonderfulcronjob and everything should work fine.

Thanks to birdy for finding this one…

Tangotango dark emacs color theme

UPDATE : This entry is deprecated ! Source code has been moved to Github and installation instructions have been rewritten.

I always have used the default Emacs color theme, with a white background. Recently I wanted to switch to a dark background but didn’t find a color scheme taht I’d like enough to use, so Is tarted to create one myself. In fact I started with the tango color theme on EmacsWiki, modified a bit, and added some faces to support gnus and org-mode as I use them a lot.

The result is a color theme named tangotango whose code is the following :

(defun color-theme-tangotango ()
  "A color theme based on Tango Palette."
  (interactive)
  (color-theme-install
   '(color-theme-tango
     ((background-color . "#2e3436")
      (background-mode . dark)
      (border-color . "#888a85")
      (cursor-color . "#fce94f")
      (foreground-color . "#eeeeec")
      (mouse-color . "#8ae234"))
     ((help-highlight-face . underline)
      (ibuffer-dired-buffer-face . font-lock-function-name-face)
      (ibuffer-help-buffer-face . font-lock-comment-face)
      (ibuffer-hidden-buffer-face . font-lock-warning-face)
      (ibuffer-occur-match-face . font-lock-warning-face)
      (ibuffer-read-only-buffer-face . font-lock-type-face)
      (ibuffer-special-buffer-face . font-lock-keyword-face)
      (ibuffer-title-face . font-lock-type-face))
     (highlight ((t (:background "brown4" :foreground nil))))
     (border ((t (:background "#888a85"))))
     (fringe ((t (:background "grey10"))))
     (mode-line ((t (:foreground "#bbbbbc" :background "#222222" :box (:line-width 1 :color nil :style released-button)))))
     (mode-line-inactive ((t (:foreground "#bbbbbc" :background "#555753"))))
     (mode-line-buffer-id ((t (:bold t :foreground "orange" :background nil))))
     (region ((t (:background "dark slate blue"))))
     (link ((t (:underline t :foreground "dodger blue"))))
     (custom-link ((t (:inherit 'link))))
     (match ((t (:bold t :background "#e9b96e" :foreground "#2e3436"))))
     (tool-tips ((t (:inherit 'variable-pitch :foreground "black" :background "lightyellow"))))
     (tooltip ((t (:inherit 'variable-pitch :foreground "black" :background "lightyellow"))))
     (bold ((t (:bold t :underline nil :background nil))))
     (italic ((t (:italic t :underline nil :background nil))))
     (font-lock-builtin-face ((t (:foreground "#729fcf"))))
     (font-lock-comment-face ((t (:foreground "#888a85"))))
     (font-lock-constant-face ((t (:foreground "#8ae234"))))
     (font-lock-doc-face ((t (:foreground "#888a85"))))
     (font-lock-keyword-face ((t (:foreground "#729fcf" :bold t))))
     (font-lock-string-face ((t (:foreground "#ad7fa8" :italic t))))
     (font-lock-type-face ((t (:foreground "#8ae234" :bold t))))
     (font-lock-variable-name-face ((t (:foreground "tomato"))))
     (font-lock-warning-face ((t (:bold t :foreground "#f57900"))))
     (font-lock-function-name-face ((t (:foreground "#edd400" :bold t))))
     (comint-highlight-input ((t (:italic t :bold t))))
     (comint-highlight-prompt ((t (:foreground "#8ae234"))))
     (isearch ((t (:background "#f57900" :foreground "#2e3436"))))
     (isearch-lazy-highlight-face ((t (:foreground "#2e3436" :background "#e9b96e"))))
     (show-paren-match-face ((t (:foreground "#2e3436" :background "#73d216"))))
     (show-paren-mismatch-face ((t (:background "#ad7fa8" :foreground "#2e3436"))))
     (minibuffer-prompt ((t (:foreground "#729fcf" :bold t))))
     (info-xref ((t (:foreground "#729fcf"))))
     (info-xref-visited ((t (:foreground "#ad7fa8"))))
     (diary-face ((t (:bold t :foreground "IndianRed"))))
     (eshell-ls-clutter-face ((t (:bold t :foreground "DimGray"))))
     (eshell-ls-executable-face ((t (:bold t :foreground "Coral"))))
     (eshell-ls-missing-face ((t (:bold t :foreground "black"))))
     (eshell-ls-special-face ((t (:bold t :foreground "Gold"))))
     (eshell-ls-symlink-face ((t (:bold t :foreground "White"))))
     (widget-button ((t (:bold t))))
     (widget-mouse-face ((t (:bold t :foreground "white" :background "brown4"))))
     (widget-field ((t (:foreground "orange" :background "gray30"))))
     (widget-single-line-field ((t (:foreground "orange" :background "gray30"))))
     (custom-group-tag ((t (:bold t :foreground "#edd400" :height 1.3))))
     (custom-variable-tag ((t (:bold t :foreground "#edd400" :height 1.1))))
     (custom-face-tag ((t (:bold t :foreground "#edd400" :height 1.1))))
     (custom-state-face ((t (:foreground "#729fcf"))))
     (custom-button  ((t (:box (:line-width 1 :style released-button) :background "grey50" :foreground "black"))))
     (custom-variable-button ((t (:inherit 'custom-button))))
     (custom-button-mouse  ((t (:inherit 'custom-button :background "grey60"))))
     (custom-button-unraised  ((t (:background "grey50" :foreground "black"))))
     (custom-button-mouse-unraised  ((t (:inherit 'custom-button-unraised :background "grey60"))))
     (custom-button-pressed  ((t (:inherit 'custom-button :box (:style pressed-button)))))
     (custom-button-mouse-pressed-unraised  ((t (:inherit 'custom-button-unraised :background "grey60"))))
     (custom-documentation ((t (:italic t))))
     (message-cited-text ((t (:foreground "#edd400")))) 
     (gnus-cite-face-1 ((t (:foreground "#ad7fa8"))))
     (gnus-cite-face-2 ((t (:foreground "sienna4"))))
     (gnus-cite-face-3 ((t (:foreground "khaki4"))))
     (gnus-cite-face-4 ((t (:foreground "PaleTurquoise4"))))
     (gnus-group-mail-1-empty-face ((t (:foreground "light cyan"))))
     (gnus-group-mail-1-face ((t (:bold t :foreground "light cyan"))))
     (gnus-group-mail-2-empty-face ((t (:foreground "turquoise"))))
     (gnus-group-mail-2-face ((t (:bold t :foreground "turquoise"))))
     (gnus-group-mail-3-empty-face ((t (:foreground "#729fcf"))))
     (gnus-group-mail-3-face ((t (:bold t :foreground "#edd400"))))
     (gnus-group-mail-low-empty-face ((t (:foreground "dodger blue"))))
     (gnus-group-mail-low-face ((t (:bold t :foreground "dodger blue"))))
     (gnus-group-news-1-empty-face ((t (:foreground "light cyan"))))
     (gnus-group-news-1-face ((t (:bold t :foreground "light cyan"))))
     (gnus-group-news-2-empty-face ((t (:foreground "turquoise"))))
     (gnus-group-news-2-face ((t (:bold t :foreground "turquoise"))))
     (gnus-group-news-3-empty-face ((t (:foreground "#729fcf"))))
     (gnus-group-news-3-face ((t (:bold t :foreground "#edd400"))))
     (gnus-group-news-low-empty-face ((t (:foreground "dodger blue"))))
     (gnus-group-news-low-face ((t (:bold t :foreground "dodger blue"))))
     (gnus-header-name-face ((t (:bold t :foreground "#729fcf"))))
     (gnus-header-from ((t (:bold t :foreground "#edd400"))))
     (gnus-header-subject ((t (:foreground "#edd400"))))
     (gnus-header-content ((t (:italic t :foreground "#8ae234"))))
     (gnus-header-newsgroups-face ((t (:italic t :bold t :foreground "LightSkyBlue3"))))
     (gnus-signature-face ((t (:italic t :foreground "dark grey"))))
     (gnus-summary-cancelled-face ((t (:background "black" :foreground "yellow"))))
     (gnus-summary-high-ancient-face ((t (:bold t :foreground "rotal blue"))))
     (gnus-summary-high-read-face ((t (:bold t :foreground "lime green"))))
     (gnus-summary-high-ticked-face ((t (:bold t :foreground "tomato"))))
     (gnus-summary-high-unread-face ((t (:bold t :foreground "white"))))
     (gnus-summary-low-ancient-face ((t (:italic t :foreground "lime green"))))
     (gnus-summary-low-read-face ((t (:italic t :foreground "royal blue"))))
     (gnus-summary-low-ticked-face ((t (:italic t :foreground "dark red"))))
     (gnus-summary-low-unread-face ((t (:italic t :foreground "white"))))
     (gnus-summary-normal-ancient-face ((t (:foreground "royal blue"))))
     (gnus-summary-normal-read-face ((t (:foreground "lime green"))))
     (gnus-summary-normal-ticked-face ((t (:foreground "indian red"))))
     (gnus-summary-normal-unread-face ((t (:foreground "white"))))
     (gnus-summary-selected ((t (:background "brown4" :foreground "white"))))
     (message-header-name-face ((t (:foreground "tomato"))))
     (message-header-newsgroups-face ((t (:italic t :bold t :foreground "LightSkyBlue3"))))
     (message-header-other-face ((t (:foreground "LightSkyBlue3"))))
     (message-header-xheader-face ((t (:foreground "DodgerBlue3"))))
     (message-header-subject ((t (:foreground "white"))))
     (message-header-to ((t (:foreground "white"))))
     (message-header-cc ((t (:foreground "white"))))
     (org-hide ((t (:foreground "#2e3436"))))
     (org-level-1 ((t (:bold t :foreground "dodger blue" :height 1.5))))
     (org-level-2 ((t (:bold t :foreground "#6ac214" :height 1.2))))
     (org-level-3 ((t (:bold t :foreground "#edd400" :height 1.1))))
     (org-level-4 ((t (:bold t :foreground "tomato" :height 1.0))))
     (org-date ((t (:underline t :foreground "magenta3"))))
     (org-footnote  ((t (:underline t :foreground "magenta3"))))
     (org-link ((t (:foreground "skyblue2" :background "#2e3436"))))
     (org-special-keyword ((t (:foreground "brown"))))
     (org-verbatim ((t (:foreground "#eeeeec" :underline t :slant italic))))
     (org-block ((t (:foreground "#bbbbbc"))))
     (org-quote ((t (:inherit org-block :slant italic))))
     (org-verse ((t (:inherit org-block :slant italic))))
     (org-todo ((t (:bold t :foreground "Red"))))
     (org-done ((t (:bold t :foreground "ForestGreen"))))
     (anything-header ((t (:bold t :background "grey15" :foreground "#edd400"))))
)))

Obviously you need to install and configure the color-theme Emacs extension to use it. You will find instructions on the dedicated EmacsWiki page. The setup I use is the following :

(require 'color-theme)
(color-theme-initialize)
(setq color-theme-is-global t)
(setq color-theme-is-cumulative t)
(setq color-theme-load-all-themes nil)

(color-theme-tangotango)

(add-hook 'message-mode-hook 'color-theme-tangotango)
(add-hook 'gnus-article-mode-hook 'color-theme-tangotango)

(add-hook 'after-make-frame-functions
	  (lambda (frame)
	    (set-variable 'color-theme-is-global nil)
	    (select-frame frame)
	    (if window-system
		(color-theme-tangotango)
	      (color-theme-tty-dark))))

Here is a screenshot of the color theme with an emacs-lisp file :

tangotango_elisp.png

One with a Gnus summary and article buffers :

tangotango_gnus.png

And one with an org-mode buffer :

tangotango_org.png

Feel free to give any feedback !

jeudi 3 septembre 2009

Problème d'encodage dans des session SSH

Ça fait un moment que je cherchais la solution à un problème assez banal : je me connectais en SSH à un serveur tournant en iso-8859-1 depuis un autre serveur tournant lui en utf-8. Résultat : l'édition de fichiers comportant des caractères hors-ASCII était tout simplement impossible…

Je viens de trouver une solution grâce à cette page :

La solution est un petit programme qui s'appelle luit, et qui est disponible dans le paquet x11-utils :

# apt-get install x11-utils

Une fois le paquet installé, il suffit d'appeler lui juste avant d'appeler ssh en lui indiquant l'encodage du serveur de destination via le paramètre encoding. Dans le cas cité précdemment (connexion d'un serveur en UTF-8 vers un serveur en iso-8859-1) ça fait donc :

$ luit -encoding iso-8859-1 ssh user@server
Et voilou…

mardi 16 juin 2009

Modifier le raccourci clavier de rechargement (Mod+q) dans Xmonad

Ça fait maintenant un bon bout de temps que j'utilise xmonad comme window manager (après être passé par Ion3 et dwm), et je crois bien que je vais y rester au moins pour un petit moment, tant la flexibilité et la richesse des extensions est impressionnante une fois qu'on a un peu pris en main la syntaxe du fichier de configuration (écrit en Haskell).

Aujourd'hui j'avais décidé de modifier le raccourci clavier de recompilation et de rechargement dynamique de la configuration, par défaut assigné à Mod+q. Le problème est que j'utilise Mod+s fréquemment pour un afficher un terminal de type scratchpad, et que j'ai tendance à faire des Mod+q à la place de Mod+s. Je souhaitais donc réassigner la commande Mod+q à Ctrl+Mod+q.

Pour cela, il faut aller voir dans le fichier de configuration par défaut à quelle commande est associé Mod+q, d'autant que cela semble avoir changé dans une récente version d'xmonad. La config par défaut se trouve dans le paquet libghc6-xmonad-doc, qu'il faut donc installer :

sudo apt-get install libghc6-xmonad-doc
zless /usr/share/doc/libghc6-xmonad-doc/examples/xmonad.hs.gz

On voit alors que par défaut Mod+q est associée à :

restart "xmonad" True

Il suffit donc de modifier la partie raccourcis clavier de son ~/.xmonad/xonad.hs en ajoutant quelque chose comme :

    , ((modMask .|. controlMask,  xK_q  ), restart "xmonad" True)
, ((modMask, xK_q ), spawn "")

Et voilou !

mercredi 11 mars 2009

How to display your identi.ca timeline on your blog

I recently tried to use identi.ca, a microblogging service similar to Twitter, but with a big difference : it is a free web application based on the free microblogging software Laconica.

One thing I rapidly tried to do is to display my user timeline on this blog, as many Twitter users do. Fortunately I found a great little javascript written by Kent Brewster and called identica-badge, which does 99% of what I wanted. I only tweaked it a little bit in order to display my user timeline (instead of my friends timeline), to add a link to the identi.ca and (optionnaly) twitter user page, etc.

Since Kent kindly answer to my licence question on this post’s comments, the file can be downloaded and is ditributed under a Creative Commons 3.0 attributions, noncommercial, share-alike licence :

To use it, just edit the javascript file to adapt the configuration settings (in the loadDefaults function), and call it from any HTML-like file with :

<div id="identica_update_list">
<script type="text/javascript" src="/path/to/identica-badge.js"></script>
</div>

mercredi 4 mars 2009

Éditer un blog sous Dotclear directement depuis Emacs

Il est en effet possible de poster des billets ou d'éditer des billets déjà existants directement depuis Emacs, avec quelques limitations : les billets sont rédigés en HTML (pas de syntaxe Wiki), il n'est pas possible d'ajouter des images ou des fichiers joints, et les tags ne sont pas gérés.

Pour cela, nous allons utiliser weblogger.el et décrire les étapes nécessaires à sa configuration.

Première chose, télécharger les fichiers xml-rpc.el et weblogger.el et les placer quelque part dans son load-path.

Ensuite, on modifie son .emacs et on y ajoute :

(require 'weblogger)

Si vous souhaitez que weblogger se souvienne de vos mots de passe de connexion, vous pouvez également ajouter :

(setq weblogger-save-password t)

Connectez-vous à votre Dotclear, sélectionnez le blog souhaité et allez sur la page Paramètres du blog. Là, activez l'interface XML-RPC et notez, en bas de page, les indications données sur cette interface, notamment l'URL et le numéro d'identifiant.

Retournez ensuite dans Emacs et faites un M-x weblogger-setup-weblog, et répondez aux questions posées à l'aide des paramètres donnés par Dotclear. À la fin, donnez un nom à cette configuration.

Vous pouvez recommencer les deux étapes précédentes si vous souhaitez éditer plusieurs blogs différents avec weblogger.

À cette étape vous pouvez utiliser weblogger directement en faisant M-x weblogger-start-entry par exemple, et en vous référant aux raccourcis indiqués directement dans le fichier weblogger.el. En gros, utilisez C-x C-s pour enregistrer et publier votre nouveau billet, C-c C-p et C-c C-n pour naviguer parmi les billets déjà existants, etc. Pour attribuer une catégorie à un billet, vous pouvez l'ajouter dans le champ Keywords, mais en utilisant le nom interne de Dotclear (ainsi pour ce billet, j'ai utilisé Linux-debian et non Linux, Debian, etc..

Comme j'édite plusieurs blogs différents, j'ai créé des fonctions me permettant de passer facilement de l'un à l'autre (même si ça a l'air déjà possible avec les fonctions fournies par weblogger.

Par exemple, pour sélectionner le blog Humus numericus, j'ai créé la fonction ad hoc suivante (en remplaçant la chaîne "Humus numericus" par le nom donné à la configuration lors de l'appel à weblogger-setup-weblog) :

(defun jb-hn ()
  "Lance Weblogger sur Humus numericus"
  (interactive)
  (weblogger-select-configuration "Humus numericus")
  (weblogger-fetch-entries)
  (weblogger-start-entry))

Il suffit alors de faire un M-x jb-hn pour basculer directement sur un nouveau billet du blog choisi. On peut de la sorte créer autant de fonctions qu'on a de blogs à éditer...

Mise à jour 2009-06-16 : Depuis peu, j'avais des problèmes avec weblogger et Dotclear, les billets composés en HTML voyaient les balises transformées en entités. J'ai résolu la chose en modifiant le fichier xml-rpc.el, ligne 356, en remplaçant :

`((value nil (string nil ,(url-insert-entities-in-string value))))
Par :
`((value nil (string nil ,value)))

Synchroniser Liferea entre deux systèmes

Jusqu'à présent j'utilisais Netvibes pour suivre mes différents flux RSS, mais j'ai fini par y trouver deux inconvénients majeurs :

  • les problèmes de respect de la vie privée liés au fait de confier à une boîte privée l'ensemble de ses lectures quotidiennes ;
  • la relative lenteur de l'interface en Ajax qui, bien que pas mal foutue du tout, avait tendance à rallonger le temps déjà bien trop long passé quotidiennement à suivre mes flux.

J'ai donc choisi de me porter plutôt vers un vrai lecteur RSS, en l'occurrence liferea, qui me semble avoir le plus de fonctionnalités.

Le problème était alors d'arriver à synchroniser l'état de lecture des différents fils entre les différentes machines sur lesquelles je travaille, problème d'autant plus délicat que la base sqlite utilisée par liferea pour stocker ces informations est plutôt du genre «sensible».

Je suis heureusement tombé sur un script de synchronisation depuis un blog norvégien :

Ce script ne correspond pas à mon cas de figure, car il effectue la synchronisation directement entre les deux machines via SSH, tandis que dans mon cas je passe par un serveur intermédiaire pour stocker les données depuis une machine et les récupérer sur l'autre, ce qui simplifie en partie le travail. J'ai donc utilisé le script comme base de départ pour arriver au résultat suivant :

#!/bin/bash
# Source : http://www.rolfs.no/2008/03/26/sync-lifereash-syncing-script/
# DEBUT CONFIGURATION
DIR=/home/julien/.liferea_1.4
BACKUPDIR=$DIR/backup/`date --rfc-3339=date`
REMOTE="z" # ip of remote machine
REMOTEDIR=$DIR
if [ "xjulien" = "x`whoami`" ]; then
echo "User is julien: OK"
else
echo "Only run as user julien"
exit 1
fi
# FIN CONFIGURATION
test -e /tmp/sync-liferea_has_run && rm /tmp/sync-liferea_has_run
echo "--- Syncing Liferea ---"
pgrep liferea-bin && {
echo "Liferea is running. Stopping it."
pkill liferea-bin
sleep 1
}
test -e $DIR/liferea.db || {
echo "ERROR: $DIR/liferea.db does not exist"
exit 1
}
test -e $DIR/feedlist.opml || {
echo "ERROR: $DIR/feedlist.opml does not exist"
exit 1
}
test -e $DIR/liferea.db-journal && {
echo "ERROR: liferea.db-journal exists in $DIR/"
echo "Unclean shutdown or is liferea still running? Find out/fix, then rerun liferea-sync."
exit 1
}
echo "Creating $BACKUPDIR"
mkdir -p $BACKUPDIR
echo "Making backup to $BACKUPDIR"
cp -v $DIR/feedlist.opml $BACKUPDIR/
cp -v $DIR/liferea.db $BACKUPDIR/
cp -v $DIR/feedlist.opml.backup $BACKUPDIR/
# Using rsync to preserve when file was last changed..
echo ""
echo "--- Syncing IN ---"
echo ""
rsync -vazu -e "ssh"  -f '+ /feedlist.opml' -f '+ /feedlist.opml.backup' -f '+ /liferea.db' -f '- **'  $REMOTE:$REMOTEDIR/ $DIR
echo ""
echo "--- Syncing OUT ---"
echo ""
rsync -vazu -e "ssh" -f '+ /feedlist.opml' -f '+ /feedlist.opml.backup' -f '+ /liferea.db' -f '- **' $DIR/ $REMOTE:$REMOTEDIR
touch /tmp/sync-liferea_has_run && exit 0

L'utilisation du fichier temporaire /tmp/sync-liferea_has_run est parfaitement optionnelle, elle me permet juste de ne lancer liferea automatiquement au démarrage de ma session X que si la synchronisation a bien eu lieu. Pour cela j'ai juste rajouté la ligne suivante dans mon ~/.xsession :

while [ ! -e /tmp/sync-liferea_has_run ]; do sleep 1; done && liferea-bin &

- page 2 de 10 -