Diaspora & panurgisme
Posted by JB on 17/05/10 at 05:30
C’est le truc qui m’aura énervé dans les news informatiques des 2 dernières semaines. De nombreux signaux tendent à montrer que Facebook se soucie de moins en moins du respect des données privées de ses utilisateurs. 60% des utilisateurs penseraient même à quitter Facebook. Et voilà qu’on a droit à un festival d’articles sur 4 gus qui ont levé 170k€ et des bananes pour monter une alternative libre à Facebook, Diaspora.
Libre ? Ah euh oui, enfin un jour quoi. Déjà quand il y aura quelque chose à montrer. Pour l’instant, il n’y a rien, il y a de la com’ et c’est tout. Les formats d’échange ? Les technos qui seront employées/supportées ? On n’en sait rien. Il y a là juste du buzz, juste des mecs qui ont levé du fric sur rien. Même le grand Tristant Nitot se fait prendre à un enthousiasme un peu absurde.
Seulement la messe semble dite, ce projet va dans le mur. Comme je n’ai pas eu le temps d’écrire cet article en temps et en heure, d’autre ont bien résumé la situation pour moi, et je ne peux qu’approuver :
- 7 raisons pour lesquelles Diaspora, l’alternative ouverte à Facebook est condamnée d’avance chez Frédéric de Villamil, mister Typo
- Diaspora’s Curse par Jason Fried de chez 37signals
C’est lamentable qu’on fasse de la pub à quelque chose qui n’est rien, juste parce que le Times en a fait un article. Qui plus est quand on voit fleurir les alternatives tangibles, comme Movim, avec du vrai code, des trucs qu’on peut essayer, tout ça..
Bêêêêh !
Redmine supporte à ce jour 37 langues. Si vous souhaitez diffuser votre plugin, c’est une bonne idée de respecter les mêmes conventions que le core, pour en faciliter les traductions, voire proposer plusieurs traductions de votre plugin directement. C’est ce que je fais par exemple pour mon plugin “Datacenter” que je livre en anglais et en français (voir la page de wiki française).
Pour cela, Redmine utilise l’internationalisation de Rails. Chaque mot ou groupe de mot qui doit être traduit est associé à une clé unique. Chaque langue a son fichier YAML dans le dossier config/locales/, et dans ce fichier on indique que telle clé correspond à telle chaine de caractères. Par exemple, plutôt que d’écrire “Mon super plugin” directement dans vos vus et helpers, vous allez lui associer une clé de votre choix, mettons text_my_super_plugin.
Dans la vue, vous pourrez utiliser le helper l() (un L minuscule) de cette façon :
<%= l(:text_my_super_plugin) %>Ensuite vous devrez associer cette clé à sa valeur pour chaque langue. Pour le français, le fichier config/locales/fr.yml de votre plugin ressemblera à ça :
fr: text_my_super_plugin: Mon super plugin
Et vous pouvez traduire votre appli en anglais, en ajoutant un fichier config/locales/en.yml contenant :
en: text_my_super_plugin: My great plugin
Pour un texte accentué ou comportant des caractères spéciaux, il suffira de mettre la chaine entre quotes pour éviter toute confusion lors de l’analyse du fichier. Attention à ce que votre fichier reste bien en UTF8 tout de même.
Si la traduction n’existe pas (fichier de langue manquant ou clé inexistante dans la langue de l’utilisateur), Redmine affichera une erreur. C’est la que le helper l_or_humanize peut être utile :
<%= l_or_humanize(:super_plugin) %>Si la clé existe, elle sera remplacée par sa traduction. Si non, Rails tentera d’en faire une chaine pour humain (remplacement des underscores par des espaces, majuscule à la première lettre, etc.). En l’occurrence Super plugin.
Pour les affichages de dates, heures, temps ou intervalles de temps, il existe des helpers beaucoup plus évolués que ceux présentés ci-dessus. Ils sont définis dans lib/redmine/i18n.rb. En voici une liste, ainsi que comment les tester dans une console Rails :
% ruby script/console Loading production environment (Rails 2.3.5) >> include Redmine::I18n => Object >> set_language_if_valid('fr') => :fr >> l_hours(5) => "5.00 heures" >> format_date(Time.now) => "26/04/2010" >> format_time(Time.now) => "26/04/2010 19:55" >> day_name(1) => "lundi" >> month_name(3) => "mars"
A des fins de test, le helper ll() permet de préciser d’abord la locale avant la clé et ainsi de tester une clé dans une locale particulière :
>> ll("fi", :field_mail) => "Sähköposti"
Dernière chose, il est possible d’utiliser des variables dans vos fichiers de langue. Ils seront interpolés lors du rendu de la vue. Si vous n’avez qu’une variable à mettre, vous pouvez utiliser le nom “value” et passer la valeur dans votre vue directement en 2e argument de votre l(). Si vous avez 2 variables ou plus, il faut leur donner un nom et passer un hash en 2e argument de l() dans votre vue. Evidemment ces valeurs peuvent elles-même faire appel à vos traductions pour éviter de dupliquer des traductions.
Un exemple vaut mieux qu’un long discours. Avec ce fichier de langue :
fr: label_draft_saved_time: "Brouillon sauvegardé à {{value}}" label_draft_pending: "Brouillon en attente, sauvegardé il y a {{time}} : {{restore}} ou {{delete}}" label_draft_restore: "restaurer" label_draft_delete: "supprimer"
Je peux faire appel à ceci dans mes vues (les valeurs de temps sont bidon) :
<%= l(:label_draft_saved_time, format_time(Time.now)) %> <%= l(:label_draft_pending, {:time => format_time(Time.now), :restore => l(:label_draft_restore), :delete => l(:label_draft_delete)}) %>
J’essaierai de documenter tout ça en anglais dans le wiki Redmine un de ces 4.
Il peut arriver qu’une classe de Redmine ne se comporte pas exactement comme vous le voudriez, ou que vous souhaitiez lui ajouter des propriétés.
C’est décrit en anglais sur la page Plugin Internals / Extending the Redmine Core du wiki officiel, qui renvoie vers la lecture de certains plugins d’Eric Davis pour des exemples.
Petit apparté, je partage assez l’analyse selon laquelle il est quasi inutile de maintenir une API pour surcharger les modèles / controlleurs. Cela dit, parfois les méthodes sont extrêmement longues et/ou sujettes à de fréquents changements. Toute surcharge dans un plugin induit donc un risque pour les futures versions du core…
Retour à nos moutons : admettons qu’on veuille ajouter au modèle Issue une méthode d’instance whoami qui retournerait “Je suis le ticket #XXX”. Exemple bidon, c’est pour la science.
Si on applique ce que préconise Eric, ça donne quelque chose de ce genre :
#init.rb require_dependency 'issue_patch' Dispatcher.to_prepare do Issue.send(:include, IssuePatch) unless Issue.included_modules.include? IssuePatch end #lib/issue_patch.rb require_dependency 'issue' module IssuePatch def self.included(base) base.extend(ClassMethods) base.send(:include, InstanceMethods) base.class_eval do unloadable #permet de décharger la classe en mode dev end end #ici nos méthodes de classe module ClassMethods end #ici nos méthodes d'instance module InstanceMethods def whoami "Je suis le ticket ##{self.id}" end end end
Classique, mais comme diraient certains amis “on voit pas trop ce que ça fait”.
Personnellement je préfère réouvrir la classe Issue, et ça a l’air de marcher tout aussi bien (en dev et en prod) :
#init.rb config.to_prepare do require_dependency 'issue_patch' end #lib/issue_patch.rb require_dependency 'issue' class Issue def whoami "Je suis le ticket ##{self.id}" end end
Différences :
- utilisation de “config” au lieu de “Dispatcher” ; sans importance à mon avis. C’est discuté un peu ici.
- ré-ouverture de la classe plutôt qu’inclusion d’un module ; je trouve ça plus lisible pour ce coup-ci
Attention, je ne dis pas que ce que fait Eric fonctionne moins bien. Au contraire, c’est peut-être plus “propre”, mais n’étant pas un développeur confirmé, si je ne comprends pas au premier coup d’oeil ce que j’ai fait, j’ai plus de mal à maintenir mon code.
Au passage, c’est une mauvaise idée d’appeler son patch “lib/issue_patch.rb”. Si tout le monde fait ça, on ne pourra pas faire fonctionner 2 plugins qui patchent la même classe en même temps. Beurk. D’ailleurs, c’était le cas pour des plugins à moi, donc autant utiliser des noms a priori uniques : commit redmine_drafts/ec06b8
Execute, chef : oui mais par qui ?
Posted by JB on 17/04/10 at 21:00
Un billet en forme de petite note pour moi-même, relatif à mes découvertes de la soirée.
J’ai besoin d’exécuter des commandes avec Chef. Pour cela, il y a la ressource Execute :
execute "ma commande"Mais la documentation prévient bien :
By their nature, Execute resources are not idempotent, as they are completely up to the user’s imagination. Use the not_if or only_if meta parameters to guard the resource for idempotence.
OK, allons-y :
execute "ma commande" do not_if "ma condition shell" end
Si la commande doit être exécutée avec un user particulier :
execute "ma commande" do user "tom" not_if "ma condition shell" end
Mais la condition, elle, sera exécutée dans un contexte root (puisqu’il vaut mieux lancer chef-solo ou chef-client en root si l’on veut que la plupart des ressources fonctionnent). En général la condition serait à exécuter avec le même user. D’où :
execute "ma commande" do user "tom" not_if "ma condition shell", :user => "tom" end
Je trouve pas ça très joli. A réfléchir.
PS: si on veut se convaincre que ça se passe bien comme je dis :
execute "whoami > /tmp/whoami.execute" do user "tom" only_if "whoami > /tmp/whoami.only_if" end
Chef la recette !
Posted by JB on 23/03/10 at 17:52
Après avoir comparé au boulot 3 outils de gestion de conf, j’en retiens les éléments suivants :
- Cfengine : DSL spécifique et horrible à apprendre, orientations peu claire (à-la-Nagios), une communauté amorphe, pas hackable. Poubelle.
- Puppet : en ruby, un DSL spécifique pour les confs (bof), a fait ses preuves, une bonne doc, de plus en plus hackable (la doc s’améliore de jour en jour), une communauté dynamique, et le projet est géré sous redmine. Sympa.
- Chef : en ruby, tout en ruby, donc pas de DSL à apprendre (yeah!), une doc pas mal, hackable à l’infini, le projet est hyper mega dynamique, et ils ont des références énormes dans le monde ruby, du genre 37signals ou Engine Yard. Adopté !
Seul défaut de Chef, ça bouge vite, très vite. Et les versions 0.7 présentes dans mes distrib préférées commencent à être vraiment dépassées.
Hier je me prends donc par la main, en m’inspirant de l’article de akitaonrails, et je cherche comment installer une 0.8. Miracle, tout est dans leur wiki, et ils proposent même des dépôts pour ma Ubuntu Lucid.
Voici un script chef-install pondu en 3 secondes :
#installation
add-apt-repository ppa:jtimberman/opschef
aptitude update
aptitude -y install chef
service chef-client stop
update-rc.d chef-client disable >/dev/null
#configuration
sed -i -e 's#^file.*#file_cache_path "/tmp/chef-solo"#' \
-e 's#^cook.*#cookbook_path ["/var/chef-solo/cookbooks"]#' /etc/chef/solo.rb
#cookbooks (install 'git-core' if needed)
mkdir -p /var/chef-solo
cd /var/chef-solo
git clone http://github.com/opscode/cookbooks.git
#hyperspace!
cat >/etc/chef/recipes.json <<EOF
{
"resolver": {"nameservers":["192.168.0.1"], "search":"home"},
"recipes": ["resolver"]
}
EOFGo ?
% sudo chef-solo -j /etc/chef/recipes.json [Tue, 23 Mar 2010 13:47:37 +0100] INFO: Starting Chef Solo Run [Tue, 23 Mar 2010 13:47:42 +0100] WARN: Missing gem 'right_aws' [Tue, 23 Mar 2010 13:47:42 +0100] WARN: Missing gem 'mysql' [Tue, 23 Mar 2010 13:47:43 +0100] INFO: Updating template[/etc/resolv.conf] at /etc/resolv.conf [Tue, 23 Mar 2010 13:47:43 +0100] INFO: Backing up template[/etc/resolv.conf] to /etc/resolv.conf.chef-20100323134743 [Tue, 23 Mar 2010 13:47:43 +0100] INFO: Chef Run complete in 5.588404 seconds
Yeeehaa !
Mon fonctionnement actuel m’empêche de m’attacher à un serveur central et ainsi fonctionner en client/serveur. Je pense que je vais donc commencer à me faire des cookbooks et les utiliser “bêtement” via chef-solo, à voir.
Enfin pour l’instant, c’est juste énorme.
Schema-Free MySQL contre NoSQL
Posted by JB on 19/03/10 at 17:00
En ce moment il y a une vague d’engouement pour les bases non-SQL, comme les bases orientées document CouchDB ou MongoDB. J’ai lu un article récemment qui vaut le détour : Schema Free Mysql VS NoSQL (via). Ce genre de solution permettrait sûrement de faire passer la pillule plus doucement aux gens qui s’accrochent encore au SQL pur à l’ancienne.
Au passage, juste une citation qu’on croirait destinée à certains ayatollahs du boulot :
Open your mind. FriendFeed uses something very similiar to this to handle 250 million entries. Why is it no good for the theorists? Because they don’t solve problems, they make them.
.irbrc pour Rails 3
Posted by JB on 17/03/10 at 19:22
J’utilise souvent IRB. Très souvent pour d’autres choses que Rails (à la base on me paye pour être sysadmin, pas développeur…).
Là arrive Rails 3 beta :
- qui s’appuie sur IRB pour sa console (
rails console) - qui gère ses dépendances via Bundler, ce qui ne permet plus par défaut de charger des Gems en dehors de son appli
Bah oui mais là ça coince. De bêtes require dans mon .irbrc ne fonctionnent plus. Comme discuté sur la liste rails france, je charge dans mon .irbrc des choses dont j’ai très souvent besoin, et qui n’ont rien à voir avec mes applis, même en Rails 3. Par exemple, il n’y a aucune raison qu’une de mes applis dépende de Wirble, une lib pour améliorer IRB.
Bref, faute de mieux pour le moment, voilà le genre d’horreur auquel Rails me pousse :
basedirs = ENV["GEM_PATH"].to_s.split(":").map{|d|"#{d}/gems/*/lib"} Dir.glob(basedirs).each do |dir| $: << dir unless $:.include?(dir) end
Humpf.
Déplacer une base Rails
Posted by JB on 17/03/10 at 14:19
Au boulot nous avons une instance Redmine qui tourne avec une base Sqlite3 pour nos tickets internes. Pratique, mais nous avons aussi développé une offre d’hébergement Redmine ouverte à la demande sur l’intranet, sous Mysql. D’où passage de l’instance Sqlite sous Mysql.
On ne peut bien sûr pas se contenter d’un export SQL de Sqlite à réimporter sous Mysql : ces deux moteurs ne respectent pas exactement la même syntaxe SQL, et ne stockent pas leurs types primitifs de la même manière (exemple: les booléens, stockés en “1/0” sous Mysql, et en “t/f” sous Sqlite).
C’est là qu’arrive yaml_db , une biblitothèque à installer comme une gem ou comme un plugin dans une appli Rails, qui permet de réaliser des exports ou imports de sa base sous un format neutre, YAML (wikipedia).
Pour une migration “one shot”, le plus simple sera de cloner la lib dans le répertoire plugins de vos applis et de suivre les instructions proposées dans le README :
cd /path/to/my/app cd vendor/plugins git clone http://github.com/ludicast/yaml_db.git cd - rake db:dump #modifications éventuelles du fichier db/data.yml (chez nous l'appli change d'adresse, donc on a remplacé toutes les anciennes URLs) #changement de database.yml rake db:load
Un outil simple, comme on aime :)
EDIT: j’ai titré “déplacer une base Rails” car ce plugin fonctionne bien surtout avec une base ActiveRecord, ORM de Rails par défaut. Pour une base quelconque rien de garanti :)
Partie 1 : le retour de la vengeance
Posted by JB on 04/03/10 at 10:20
Que j’aurais pu aussi sobrement appeler :
- refaisons le match
- massacre à la tronçonneuse
- f*ck
require 'find' require 'yaml' require 'digest/md5' class EvaFile attr_accessor :path def initialize(path) @path = path end def infos @infos ||= {:size => File.size(@path).tap{|s| def s.to_s; "#{self.dup} bytes"; end }, :last_modified => File.mtime(@path), :md5_sum => Digest::MD5.hexdigest(File.read(@path))} end end class EvaDir def initialize(subdir) raise "Give me a (sub)directory !" if subdir.nil? || !File.directory?(subdir) @subdir = subdir end def files @files ||= Find.find(@subdir) do |f| Find.prune if File.directory?(f) EvaFile.new(f) if File.file?(f) end.compact end def write_info_file(filename) path = File.join(@subdir,filename) begin info = File.open(path,"w") rescue $stderr.puts "Error opening file #{path} for writing..." end info.write "Size: #{size} bytes\n" info.write "Files: #{nb_files}\n" files_hash = {} files.each do |file| files_hash.merge!(File.basename(file.path) => file.infos) end info.write files_hash.to_yaml info.close_write end def size @size = files.inject(0) do |memo, f| memo + f.infos[:size] end end def nb_files files.length end end class EvaUtil def initialize(dir) raise "Give me a directory !" if dir.nil? || !File.directory?(dir) @dir = dir end def subdirs return @subdirs if @subdirs @subdirs = [ EvaDir.new(@dir) ] @subdirs << Find.find(@dir) do |f| EvaDir.new(f) if File.directory?(f) end @subdirs = @subdirs.compact.uniq end def generate_info_files(filename="infos.txt") @subdirs.each do |s| s.write_info_file(filename) end end def generate_meta_info_file(filename="metainfos.txt") path = File.join(@dir,filename) begin meta = File.open(path,"w") rescue $stderr.puts "Error opening file #{path} for writing..." end meta.write "Total size: #{size} bytes" meta.write "Total number of files: #{nb_files}" meta.write "Last modified (<24h) :\n #{last_modified.join("\n ")}" if last_modified.any? meta.close_write end def last_modified @subdirs.inject([]) do |memo, subdir| memo << subdir.files.select{|f| File.mtime(f) < Time.at(Time.now.to_i - 86400)}.map(&:path) memo.flatten memo end end private def method_missing(symbol, *args) if %w(nb_files size).include?(symbol.to_s) @subdirs.inject(0) do |memo, subdir| memo + subdir.send(symbol) end else super end end end e = EvaUtil.new(ARGV[0]) e.generate_info_files e.generate_meta_info_file
Garanti 100% non testé, 100% fait sans l’API, et surtout 100% fait avec un éditeur de texte. C’est sûrement bourré de conneries, mais au moins avec un truc comme ça j’aurais pas eu honte. Cela dit vue la longueur, je commence à me pardonner d’avoir barbouillé ma copie de blanco, c’était infaisable sans ça. Coder sur papier est définitivement un cauchemard. On se la refait dans 2 ans ;-)
Un shell en ruby ?
Posted by JB on 25/02/10 at 19:00
Dans 4 jours, je vais me faire massacrer tenter un examen interne au boulot, censé valider mes aptitudes de “programmeur système”. Cet examen comporte une épreuve de développement (sur papier, faut pas déconner), que la plupart des gens vont passer en Java ou C/C++. Mais très peu pour moi, j’attaque en Ruby !
Je lis donc des bouquins, qui présentent un squelette de shell en C. Et en Ruby ? Eh bien en fait, contre toute attente, c’est super simple, voici un squelette fonctionnel :
#!/usr/bin/ruby require 'readline' require 'open3' class Rshell def initialize loop do cmd = Readline.readline("$ ") exit if cmd.nil? or cmd == "exit" Open3.popen3(cmd) do |stdin,stdout,stderr| STDOUT.print stdout.read STDERR.print stderr.read end end end end Rshell.new
Il ne faut pas s’attendre à des miracles, aucun builtin, pas de gestion du PATH, mais on peut passer des commandes, différencier éventuellement STDOUT/STDERR pour le futur.
Ca me donne l’occasion de parler d’un vrai shell en Ruby, utilisé chez Heroku, Rush. J’en reparlerai dès que j’aurai testé ça au quotidien au boulot :)
Redmine Plugins #1 : Ajouter une option vrai/faux à un plugin Redmine
Posted by JB on 20/02/10 at 15:42
Je travaille en ce moment sur des plugins Engines pour Redmine. Ces plugins me serviront au boulot, et permettront de laisser une situation un peu plus propre que les bidouillages actuels à mon départ. En particulier en avançant sur le plugin de gestion d’un datacenter (site et dépôt github), j’apprends énormément de choses sur le fonctionnement de Rails/Redmine/Engines, et j’entame donc une série d’articles sur ces découvertes. Ces articles supposent d’avoir déjà lu le tutoriel du site, et je repartirai souvent de cet exemple.
Cela donnera certainement lieu à des entrées dans le wiki redmine.org ou des suggestions dans les tickets. Et puis ça m’astreindra à publier un peu, comme le fait Eric dans ses Daily Refactor du core Redmine depuis 3 semaines et pour les mêmes raisons, et aussi suite à cet article de Damien.
Allons-y.
init.rb : on y ajoute la clé et la valeur par défaut du paramètre qu’on veut introduire, par exemple ici “boolean_parameter”. On précise également un partial qui permettra de gérer les paramètres du plugin :
settings :default => { :boolean_parameter => true }, :partial => 'settings/my_plugin'
app/views/settings/_my_plugin.html.erb : on place ici un formulaire pour gérer nos paramètres. Il sera automatiquement accessible dans la partie Administration > Plugins > lien “Configurer” sur votre plugin. “plugin_my_plugin” est à remplacer dans ce qui suit par “plugin_[nom de votre plugin]” :
<p> <label>Paramètre booléen</label> <%= check_box_tag 'settings[boolean_parameter]', 1, Setting[:plugin_my_plugin][:boolean_parameter] %> </p>
Et voilà ! Ensuite, n’importe où dans votre plugin, vous pourrez utiliser :
Setting[:plugin_my_plugin][:boolean_parameter]
En réalité en mettant “1” comme deuxième paramètre, vous ne stockerez pas un booléen, mais “1” (coché) ou “nil” (décoché). Si vous souhaitez obtenir “true” ou “false” absolument, vous pouvez utiliser :
!!Setting[:plugin_my_plugin][:boolean_parameter]
A voir en vrai ici
Hello CouchDB
Posted by JB on 08/02/10 at 18:47
On me titille de part et d’autre : Nicolas, Linux Mag (deux fois en 6 mois!), Damien et Damien, et des discussions par-ci par-là.
Donc c’est parti, j’essaie de me faire une appli sur CouchDB. Avec plein d’arrière pensées :
- mieux maitriser l’outil et les concepts sous-jacents pour mieux comprendre (et pourquoi pas contribuer à) Chef
- comparer ça à MongoDB (voir le railscast) ; si je bute trop, j’essaierai peut-être Mongo
- en finir avec le gouffre conceptuel objet/relationnel ; j’espère que ça sera concluant de ce côté :)
Je me fais une petite base de connaissances parce que le besoin commence à être vraiment trop criant. J’ai des tonnes d’items non-lus et/ou à garder dans mon reader RSS, et j’ai vraiment besoin d’un outil pour organiser ça sous forme de tags (et si possible garder des copies locales des articles).
Pour simplifier le tout, je commence à partir sur du Rails 3 :
echo 'gem "couchrest"' >> Gemfile bundle install
Des nouvelles dans les prochaines semaines, le projet sera comme d’hab’ sur github
Rails 3.0 beta is out !
Posted by JB on 07/02/10 at 20:22
Here we go :
gem install tzinfo builder memcache-client rack rack-test rack-mount erubis mail text-format thor bundler i18n gem install rails --pre
Let’s give it a try ;)
Pense-bête sur l'utilisation de LUKS
Posted by JB on 04/01/10 at 17:42
Voir la doc Ubuntu
Créer un volume encrypté :
sudo cryptsetup luksFormat -c aes -h sha256 /dev/sdb
Ajouter une clé :
sudo cryptsetup luksAddKey /dev/sdb
Voir les clés :
sudo cryptsetup luksDump /dev/sdb
Ouverture et formatage manuel :
sudo cryptsetup luksOpen /dev/sdb disk sudo mkfs.ext3 /dev/mapper/disk
Fous ta cagoule
Posted by JB on 23/12/09 at 08:54
Je regarde une rediffusion de l’intervention d’Elisabeth Badinter devant la mission d’information sur le port de la burqa. Elle est clairement contre, et elle avance des arguments intéressants en faveur d’une “interdiction” (pas forcément contraignante réglementairement ?). En particulier elle commence par discuter la liberté de se vêtir, en argumentant le fait “qu’il n’y a pas de vêtement du visage”.
Une phrase hors discours m’a interpellé lorsqu’elle évoquait la question du port du voile “pour se cacher des regards impurs d’autres hommes” :
Entre vous et moi, drôle de vision des choses de penser que tous les hommes qui regardent une femme ne rêvent que de la violer
Pom pom pom. Non ?
Enfin, comme elle le dit bien (et ça serait cool qu’un ou deux politiques se mettent au diapason), elle n’est pas spécialiste de l’Islam, ni spécialiste des lois ou de la politique, la question reste donc entière. On va voir à quel point l’UMP devient un parti populiste :-)
Vroum
Posted by JB on 22/12/09 at 19:13
Tristan Nitot a fait un billet qui m’a beaucoup intéressé hier, Quelques notes sur la culture et Internet.
Déjà ça fait des pistes de réflexion pour imaginer ce que sera la société de demain. On va nettement plus loin que les bêtises du gouvernement actuel (Christine is watching you :-)). Notamment sur le paradoxe de la disparition de la rareté avec Internet : toute l’écontomie actuelle repose sur le fait que les produits sont “rares” : si je m’achète un CD, je paye toute une ribambelle de parasites (ce n’est pas péjoratif dans cette phrase) qui ont packagé, transporté, mis en rayon, etc. la musique que je veux écouter au final. C’est là que l’informatique arrive : le transport, la duplication, voire la pub sont quasi gratuites. Comment bâtir une économie là-dessus ? Et comment les non-parasites (les créateurs pour la musique) peuvent vivre dans un tel modèle ? Le sujet mérite qu’on y réfléchisse en tout cas :)
Ensuite, à titre professionnel, je ne suis jamais aussi content que lorsque j’utilise de jolis outils libres, voire que je les adapte à mes besoins (redmine et nagios sont de parfaits exemples du genre d’errements que je peux avoir au boulot). A titre personnel, je développe un peu sur mon temps libre (voir mon espace sur Github), je n’utilise que des PCs sous des systèmes libres (ce n’est pas vrai pour mon téléphone j’admets) et j’évangélise à l’occasion autour de moi. Bref, je baigne dans cette communauté.
L’article de Tristan met un peu en lumière le moteur qui m’agite lorsque je mets à disposition des sources de mes programmes sur Internet, sans toutefois être complet. En dehors des aspects relationnels, communautaires, qui m’intéressent, je dirais que j’ai 3 moteurs dans ce genre de démarche. Dans le désordre :
- la reconnaissance des pairs ou des gens qui utiliseront mon code
- la satisfaction de penser que des gens utiliseront mon code et en seront contents : c’est proche mais tout de même différent, je n’espère pas forcément une boite de chocolat, mais je suis content de penser que ce que j’ai fait sera utile à d’autres (je pense par exemple à Teamscript 4)
- l’amélioration continue : mettre mon code à disposition sous une licence qui va bien, c’est laisser la porte ouverte à ce que d’autres gens (potentiellement bien plus compétents que moi) améliorent ce que j’ai commencé à faire ; c’est comme ça que se construisent les meilleurs produits informatiques de nos jours (à commencer par les OS)
Je trouve ces deux sujets vraiment passionnants. Dommage qu’on entende jamais ce genre de thèse à plus haut niveau, et qu’on s’arrête à la bête défense d’intérêts privés. Je suis complètement dépassé par la course folle aux profits qu’on peut soupçonner chez de nombreux parasites des milieux culturels. La motivation devrait être de faire partager ce qu’on aime, ce qui sort de notre tête ou de nous. La gloire éternelle, l’exposition médiatique, l’argent qui coule à flot… bof.
ActiveRecord::Base.logger = Logger.new(STDOUT)
(thanks)
Final countdown
Posted by JB on 20/10/09 at 12:16
Rien ne nous survivra
Posted by JB on 17/10/09 at 23:45
Quand je vois les conneries que vient de sortir Jacques Séguéla dans l’émission de Ruquier, le roman de Maïa Mazaurette que je suis en train de lire, Rien ne nous survivra – Le pire est avenir est tout de suite plus clair : il y a des vieux qu’il vaudrait mieux tuer.
Ce monsieur vient d’expliquer que le Net est la pire saloperie que l’homme ait jamais inventé, parce qu’on pouvait descendre une réputation en quelques minutes. Il parlait en l’occurrence pendant l’interview de Julien Dray, qui venait expliquer son livre, la cabale médiatique contre lui, les informations non vérifiées, mais qui dit tout de même autre chose du Net, heureusement. J’ai l’impression que ce raisonnement est en vogue chez tout un tas de vieux débris inadaptés, dont pas mal de politicons effrayés par le monde qui les entoure.
J’aime Internet, j’aime vraiment Internet. J’aime qu’Internet soit neutre, et j’espère qu’il le restera malgré la volonté de certains gouvernements dont le nôtre. J’aime échapper aux medias centralisés, avoir accès à différentes opinions sur les sujets qui m’intéressent, et je me méfie de tous ceux qui veulent en faire un minitel 2.0.
Par les temps qui courrent, ce n’est pas la Déclaration des Droits de l’Homme qui garantit les libertés d’expression ou d’opinion. C’est par exemple Twitter qui permet d’informer sur les élections en Iran, où les medias traditionnels se seraient faits tuer. Ce sont des blogueurs qui s’escriment à rendre moins lisse les informations des medias traditionnels et des agences de presse. C’est aussi les chaines que m’envoie ma mère, qui sont tantot droles tantot sérieuses, mais qui font réfléchir les gens. Cette diabolisation du Net n’a pas lieu d’être. Les gens comme Jacques Séguéla redoutent les informations non contrôlées, je veux leur dire qu’ils ont raison d’avoir peur.
Pour me remettre de bonne humeur, je finirai sur une phrase de Desproges au Tribunal des Flagrants Délires :
Jacques Séguéla est-il un con ? De deux choses l’une : ou bien Jacques Séguéla est un con, et ça m’étonnerait quand même un peu ; ou bien Jacques Séguéla n’est pas un con, et ça m’étonnerait quand même beaucoup !
Souffrance telecom
Posted by JB on 16/10/09 at 14:27
*25!!!!! * ; comme ils disaient avant, bienvenue dans la vie point com.
Et c’est Pingoo qui régale :
LIP DUB Souffrance Telecom
envoyé par Les_Graves_Infos. – Cliquez pour voir plus de vidéos marrantes.
(ahahah)