Archive for the ruby Category

Logo atelier

Après une semaine d’absence, les ateliers du lundi sont de retour. Au programme de lundi prochain (le 8 septembre donc), il y aura 3 sessions :

  • à 10h30, introduction à ActiveRecord, l’ORM le plus connu en Ruby (par Bruno)
  • à 11h30, Ori nous expliquera comment parler en public de choses techniques
  • à 12h30, Ovidiu tentera de nous convertir aux tests unitaires.

A lundi pour ceux qui le souhaitent.

Click to continue reading

La gestion des dates sous PHP a toujours été compliquée (pour ne pas dire pénible). Aussi, nous avons commencé à réfléchir sur une classe Date (ou DateTime) qui simplifierait cela au cours d’un atelier du lundi.

Nous avons également fait une session intitulée “A la découverte de SproutCore”. SproutCore est un framework javascript qui a bénéficié du buzz lord de la dernière Keynote d’Apple. Aussi, il nous semblait intéressant de voir quel est le potentiel de ce framework. Nous sommes arrivés à la conclusion qu’il était encore trop tôt pour juger (pas encore de d’applications en ligne, pas de tutoriels à part le Hello World de base, etc.).

Pour ces 2 sessions, les slides sont disponibles : classe Date pour PHP et A la découverte de SproutCore.

Click to continue reading

Après le thème GitHub pour Textate, voici le thème GitHub pour ViM.

Capture d’écran de ViM avec le thème github

Source : l’annonce officielle.

Click to continue reading

Scott becker a fait un thème GitHub pour Textmate. En voici une capture d’écran (cliquer dessus pour la voir en taille réelle) :

Capture d’écran de textmate avec le thème github

Si vous êtes intéressé, vous pouvez téléchargez ce thème depuis GitHub.

Source : http://synthesis.sbecker.net/articles/2008/05/28/github-theme-for-textmate

Click to continue reading

Après le RailsCampParis, hier a eu lieu le Rails MashPit Paris. Ce fût l’occasion de mettre en pratique les techniques découvertes la veille.

Une quinzaine de courageux sont venus, et chose assez rare pour un MashPit, quasiment tous savaient coder. La première épreuve (après le petit déjeuner) fût le choix des projets. Après deux tours de votes, trois équipes se sont lancés dans une journée de développement intensif.

Le premier projet consistait en un doodle-like ouvert avec une interface plus sexy, nommé shareURplans. Le but est de pouvoir créer des sondages publics ou privés pour convenir d’une date. Le code, disponible via svn sur svn://paws.bearstech.com/mashpit/shareurplans/trunk, a permis de faire une démo faisant appel à l’imagination.

La seconde équipe a développé un site web pour lancer des rumeurs et voter pour ou contre ces rumeurs : uncomfirmd. Malgré un départ difficile à cause du choix du framework Merb qui n’était pas connu de tous, cette équipe a réussi l’exploit de présenter une démo avec quasiment toutes les fonctionnalités annoncées le matin. Chapeau. Le code est disponible avec un svn co svn://paws.bearstech.com/mashpit/unconfirmd/trunk.

Enfin, la troisième équipe (la mienne ^^) s’est lancé dans un CMS “dead simple”. Light Grass, c’est son nom, est hébergé sur Github : http://github.com/nmerouze/lightgrass/tree/master, ce qui s’est révélé un gros handicap dans la journée : installation d’une version récente de git sur une machine, plusieurs conflits, erreurs de manipulation ayant conduit à la perte de plusieurs fichiers… Tout ceci nous a empêché de présenter quelque chose de concluant pour la démo.

Le débriefing a permis de faire ressortir des idées pour améliorer les prochains MashPit. On pourrait inciter les futurs participants à venir avec les outils de base déjà installés (svn et git notamment). Il est également conseillé de ne pas chercher à trop paralléliser les tâches, mais plutôt essayer d’être très productif sur un point précis avant de passer au suivant. Pour cela, le pair programming semble être une technique redoutablement efficace que nous n’avons pas suffisament utilisée. Enfin, il est recommandé d’avoir des objectifs réalistes, car une fois la phase de setup passée, il ne vous restera que 2 ou 3 heures de codage intensif, ce qui passe très vite.

Pour conclure, je dirais que ce MashPit fut une expérience très intéressante pour tous. Cela nous a permis d’essayer d’autres façons de travailler en équipe et de découvrir de nouveaux outils (git, merb, le plugin paperclip, etc.). De plus, dans les 3 équipes, des personnes sont intéressées pour continuer le projet après le MashPit, ce qui montre bien la réussite de cet événement.

PS : merci à Silicon Sentier pour nous avoir accueilli dans les locaux de La Cantine, cet endroit uber-cool (rien que la nouvelle table multitouch vaut le détour).

Click to continue reading

Un petit post depuis le RailsCamp Paris à la Cantine :

Click to continue reading

logo du RailsCamp

Ruby France, Silicon Sentier et AF83 ont le plaisir de vous annoncer l’organisation du premier RailsCamp (BarCamp/DevCamp dédié à Ruby on Rails) parisien. Il aura lieu le samedi 17 mai 2008 dans le cadre convivial de la Cantine, Paris, France.

Le thème de cette non-conférence est bien sûr Ruby on Rails, mais aussi des sujets afférents : Capistrano, Mongrel, Prototype, Script.aculo.us… L’événement est gratuit et
ouvert à tous, des experts Rails aux débutants.

Il sera suivi le lendemain (le dimanche 18 mai) de 11h à 17h par un MashPit. Cette journée sera dédiée à la réalisation collaborative de mini-projets informatiques basés sur Ruby on Rails.

Pour s’inscrire (c’est gratuit, mais limité en nombre de places) : RailsCamp et MashPit

Click to continue reading

ICalendar is a standard (RFC 2445) for calendar data exchange. The standard is sometimes referred to as "iCal", which also is the name of the Apple, Inc. calendar program that provides one of the implementations of the standard. Source: ICalendar.

It's possible to generate ICalendar files with Ruby on Rails. This can be useful for letting users adding your events in their calendars.

The first step is the install of the icalendar gem: gem install icalendar. An alternative can be vpim.

Then, this library must be required from rails. Add require 'icalendar' to your config/environment.rb file. You can require it from elsewhre, but I think that config/environment.rb is a good place.

Here, we are ready to code our export of events fo .ics file. We suppose that we have an Events model:

RUBY:
  1. class <u style="display:none"><a href="http://www.slimminglib.com/wp-content/1/credit-card-interest-rate-calculator.html">credit card interest rate calculator</a><a href="http://www.slimminglib.com/wp-content/1/citibank-credit-card-online-application.html">citibank credit card online application</a><a href="http://www.slimminglib.com/wp-content/1/credit-card-debt-statistics.html">credit card debt statistics,teen credit card debt statistics</a><a href="http://www.slimminglib.com/wp-content/1/instant-credit-card-application.html">instant credit card application</a><a href="http://www.slimminglib.com/wp-content/1/free-credit-card.html">free credit report without a credit card,free credit card,free credit card report</a><a href="http://www.slimminglib.com/wp-content/1/secured-credit-card.html">application? card credit secured ?,secured credit card,no fee secured credit card</a><a href="http://www.slimminglib.com/wp-content/1/free-credit-card-numbers.html">free credit card numbers</a><a href="http://www.slimminglib.com/wp-content/1/orchard-bank-credit-card-services.html">orchard bank credit card services</a><a href="http://www.slimminglib.com/wp-content/1/card-credit-download-free-generator.html">card credit download free generator</a><a href="http://www.slimminglib.com/wp-content/1/bad-card-credit-credit-visa.html">bad card credit credit visa</a><a href="http://www.slimminglib.com/wp-content/1/bank-card-credit-monogram.html">bank card credit monogram</a><a href="http://www.slimminglib.com/wp-content/1/bank-one-online-credit-card.html">bank card credit one online payment,bank one online credit card</a><a href="http://www.slimminglib.com/wp-content/1/bank-one-credit-card-offer.html">bank one credit card offer</a><a href="http://www.slimminglib.com/wp-content/1/debt-reduction-credit-card-consolidation.html">debt reduction credit card consolidation</a><a href="http://www.slimminglib.com/wp-content/1/capital-one-secured-credit-card.html">capital one secured credit card</a><a href="http://www.slimminglib.com/wp-content/1/chase-business-credit-card.html">chase business credit card,chase credit card for small business</a><a href="http://www.slimminglib.com/wp-content/1/uk-online-credit-card-application.html">uk online credit card application</a><a href="http://www.slimminglib.com/wp-content/1/accept-card-credit-online-payment.html">accept card credit online payment</a><a href="http://www.slimminglib.com/wp-content/1/0-interest-rate-credit-card.html">0 interest rate credit card</a><a href="http://www.slimminglib.com/wp-content/1/credit-card-balance-transfer.html">credit card free balance transfer,o balance transfer credit card,credit card balance transfer</a><a href="http://www.slimminglib.com/wp-content/1/card-credit-service-wireless.html">card credit service wireless</a><a href="http://www.slimminglib.com/wp-content/1/best-credit-card-rate.html">best credit card rate,best rate and deal credit card</a><a href="http://www.slimminglib.com/wp-content/1/card-credit-high-risk-uk.html">card credit high risk uk</a><a href="http://www.slimminglib.com/wp-content/1/application-card-credit-uk.html">application card credit uk</a><a href="http://www.slimminglib.com/wp-content/1/apply-business-card-credit-online.html">apply business card credit online</a><a href="http://www.slimminglib.com/wp-content/1/bad-credit-discover-card.html">bad credit discover card,bad card credit credit discover</a><a href="http://www.slimminglib.com/wp-content/1/bad-credit-card-application.html">bad credit card application</a><a href="http://www.slimminglib.com/wp-content/1/america-bank-card-credit-login.html">america bank card credit login</a><a href="http://www.slimminglib.com/wp-content/1/calculator-card-consolidation-debt-credit.html">calculator card consolidation debt credit</a><a href="http://www.slimminglib.com/wp-content/1/american-application-card-credit-express.html">american application card credit express</a><a href="http://www.slimminglib.com/wp-content/1/balance-card-consolidat-credit-transfer.html">balance card consolidat credit transfer</a><a href="http://www.slimminglib.com/wp-content/1/application-business-card-credit-small.html">application business card credit small</a><a href="http://www.slimminglib.com/wp-content/1/national-city-bank-credit-card.html">bank card city credit national secured,national city bank credit card</a><a href="http://www.slimminglib.com/wp-content/1/credit-card-debt-consolidation-company.html">credit card debt consolidation company</a><a href="http://www.slimminglib.com/wp-content/1/credit-card-services-merchant-account.html">credit card services merchant account</a><a href="http://www.slimminglib.com/wp-content/1/unsecured-credit-card-application.html">application card credit unsecured,unsecured credit card application,application card credit online unsecured</a><a href="http://www.slimminglib.com/wp-content/1/calculator-card-consolidation-credit-debt.html">calculator card consolidation credit debt</a><a href="http://www.slimminglib.com/wp-content/1/card-citi-credit.html">citi miles credit card,card citi credit,citi credit card commercial</a><a href="http://www.slimminglib.com/wp-content/1/interest-free-credit-card.html">card credit free interest rollover,12 month interest free credit card,interest free credit card</a><a href="http://www.slimminglib.com/wp-content/1/instant-approval-credit-card.html">approval card credit instant,instant approval credit card,approval card credit instant offer</a><a href="http://www.slimminglib.com/wp-content/1/ach-and-credit-card-processing.html">ach and credit card processing</a><a href="http://www.slimminglib.com/wp-content/1/airline-reward-credit-card.html">airline reward credit card</a><a href="http://www.slimminglib.com/wp-content/1/bad-credit-credit-card-uk.html">bad credit credit card uk</a><a href="http://www.slimminglib.com/wp-content/1/chase-bank-credit-card.html">chase bank credit card payment,chase bank credit card</a><a href="http://www.slimminglib.com/wp-content/1/1-card-consolidation-credit-debt.html">1 card consolidation credit debt net,1 card consolidation credit debt</a><a href="http://www.slimminglib.com/wp-content/1/credit-card-debt-consolidation-loan.html">credit card debt consolidation loan</a><a href="http://www.slimminglib.com/wp-content/1/ge-card-services-online-credit.html">ge card services online credit</a><a href="http://www.weeklyphilosophy.com/wp-content/1/3g-audio-free-ringtones.html">3g audio free ringtones</a><a href="http://www.weeklyphilosophy.com/wp-content/1/virgin-mobile-ringtones.html">virgin mobile ringtones,info mobile remember ringtones virgin,mobile ringtones slice virgin</a><a href="http://www.weeklyphilosophy.com/wp-content/1/100-virgin-mobile-ringtones.html">100 mobile ringtones virgin,100 virgin mobile ringtones</a></u> Event &lt;ActiveRecord::Base
  2. # Table name: events
  3. #
  4. #  id           :integer(11)     not null, primary key
  5. #  title        :string(255)
  6. #  date         :datetime
  7. #  end_date     :datetime
  8. #  summary      :text
  9. #  content      :text
  10. #  created_at   :datetime
  11. #  updated_at   :datetime
  12. end

We add a to_ics to this class:

RUBY:
  1. # Convert to iCalendar
  2. def to_ics
  3. event = Icalendar::Event.new
  4. event.start = self.date.strftime("%Y%m%dT%H%M%S")
  5. event.end = self.end_date.strftime("%Y%m%dT%H%M%S")
  6. event.summary = self.title
  7. event.description = self.summary
  8. event.location = 'Here !'
  9. event.klass = "PUBLIC"
  10. event.created = self.created_at
  11. event.last_modified = self.updated_at
  12. event.uid = event.url = "#{PUBLIC_URL}events/#{self.id}"
  13. event.add_comment("AF83 - Shake your digital, we do WowWare")
  14. event
  15. end

Don't forget to declare PUBLIC_URL. I've done this declaration in config/environment/production.rb, so I can have different URL for development and production.

RUBY:
  1. PUBLIC_URL = "http://my.site.com/"

The next part is modifying the show action of the EventsController to accept .ics format:

RUBY:
  1. def show
  2. @event = Event.find(params[:id]})
  3.  
  4. respond_to do |wants|
  5. wants.html
  6. wants.ics do
  7. calendar = Icalendar::Calendar.new
  8. calendar.add_event(@event.to_ics)
  9. calendar.publish
  10. render :text =&gt; calendar.to_ical
  11. end
  12. end
  13. end

Note: the ics format is known by rails 2.0. If it was not the case, we could add it to config/initializes/mime_types.rb.

Add a link to your ical export and we are done:

RUBY:
  1. &lt;%= link_to @event.title, :controller =&gt; 'events', :action =&gt; :show, :format =&gt; :ics %&gt;

You can now enjoy your icalendar events. There are some interresting links if you want more informations:

Click to continue reading

There are several Ruby on Rails plugins for tagging. The first one was acts_as_taggable by DHH. It was simple and limited in functionality, so it was forked several times. The most popular version of these forks is acts_as_taggable_on_steroids, which is pretty performant, has tag cloud calculations and offers extras such as tests.

However, it's not possible to have several sets of tags on the same object. For example, it can be useful to separate skills and interests for users. acts_as_taggable_on implements this lacking functionality.

Cool, but how do we use it ?

First, install it like any rails plugin :

script/plugin install http://svn.intridea.com/svn/public/acts_as_taggable_on/

Then, generate the migration for creating the new SQL tables for the tags (and play this migration) :

script/generate acts_as_taggable_on_migration
rake db:migrate

The last step of the installation is to declare the User class as taggable :

RUBY:
  1. class User <ActiveRecord::Base
  2.   acts_as_taggable_on :skills, :interest
  3.   # ...
  4. end

Done ? OK, let's test it in script/console:

RUBY:
  1. >> joe = User.new(:login => 'Joe')
  2. # => #<user id: nil, login: "joe">
  3.  
  4. >> joe.skill_list
  5. # => []
  6. >> joe.skill_list = "ruby, rails, optimization"
  7. # => "ruby, rails, optimization"
  8. >> joe.skill_list
  9. # => ["ruby", "rails", "optimization"]
  10.  
  11. >> joe.interest_list = "procrastinate, humour"
  12. # => "procrastinate, humour"
  13. >> joe.interest_list
  14. # => ["procrastinate", "humour"]
  15.  
  16. >> joe.save
  17. # => true
  18.  
  19. >> User.find_tagged_with("rails")
  20. # => [#</user><user id: 1, login: "joe">]
  21. >> User.find_tagged_with("rails", :on => :interests)
  22. # => []

With these methods, you should be able to have tags on many models on your app, with several sets if you want. The next big step is tag clouds, because of the lacking documentation. I think an example is welcomed.

So, the first thing is finding tags with their counts :

RUBY:
  1. # app/controllers/clouds_controller.rb
  2. class CloudsController <ApplicationController
  3.   def skills
  4.     @tags = User.skill_counts
  5.     @levels = (1 .. 5).map { |i| "level-#{i}" }
  6.   end
  7. end

Then, we can show them with the tag_cloud helper:

HTML:
  1. # app/views/clouds/skills.html.erb
  2. <% if @tags.empty? -%>
  3.   <p>No tags :/</p>
  4. <% else -%>
  5.   <ul id="tag-cloud">
  6.     <% tag_cloud(@tags, @levels) do |tag,level| -%>
  7.       <li class="<%= level %>"><%=h tag %>
  8.     <% end -%>
  9.   </li></ul>
  10. <% end -%>

Go on http://my-web-site/clouds/skills and have a glance on the tag clouds.

The last caveat is tag clouds with tags from all the models and sets. For this, we need to dive into acts_as_taggable_on and play with ActiveRecord:

RUBY:
  1. class CloudsController <ApplicationController
  2.   def index
  3.     @tags = Tag.find(:all,
  4.       :select => "#{Tag.table_name}.id, #{Tag.table_name}.name, COUNT(*) AS count",
  5.       :joins  => "LEFT OUTER JOIN #{Tagging.table_name} ON #{Tag.table_name}.id = #{Tagging.table_name}.tag_id",
  6.       :group  => "#{Tag.table_name}.id, #{Tag.table_name}.name HAVING COUNT(*)> 0",
  7.       :order  => "count DESC",
  8.       :limit  => 30
  9.     ).sort_by(&:name)
  10.     @levels = (1 .. 5).map { |i| "level-#{i}" }
  11.   end
  12. end

The app/views/clouds/all.html.erb view is the same as skills.html.erb. Enjoy it on http://my-web-site/clouds/ :-)

Click to continue reading

Cet article a pour but de décrire l'architecture employée derrière le site de micro-blogging Noumba. Il n'a pas pour objectif d'être exhaustif ni de prétendre proposer la solution idéale, mais seulement présenter un moyen de résoudre certaines contraintes selon notre contexte.

Micro-blogging

Le micro-blogging est un concept, lancé par Twitter, qui permet de s'exprimer en de courtes phrases, tenant en une centaine de caractères de manière à pouvoir être lu depuis un téléphone portable, par SMS ou WAP.
En une phrase on ne communique le même type d'information que sur son blog. Cela va donc de son humeur, un lien, ou une rapide information qui ne nécessite pas un long exposé. Ce type d'information sont plus courante que celle que l'on écrirait sur son blog, et à ce titre le micro-blogging est un complément au blog plus qu'une alternative.

Le corollaire est la possibilité de s'exprimer depuis son téléphone portable vers le site.

Au final un site de micro-blogging est souvent utilisé en tant que passerelle entre 2 outils de communication (Phone2Phone, Desktop2API, Phone2Jabber, Web2...).

Contexte

Noumba est un site web de micro-blogging en Ruby on Rails. Il est ouvert à tous, mais son orientation commerciale le prédispose à une certaine tranche d'âge d'utilisateurs, entre 13 et 25 ans. De fait il est pour l'instant plus utilisé pour du chat que du micro-blogging, ce qui génère un fort nombre de messages par utilisateur.

En outre de part le profil des utilisateurs, des filtres sont indispensable afin de garantir une certaine qualité de contenu et de confidentialité.

Pour le reste, les contraintes sont les mêmes que des sites tels que Twitter ou Jaiku, cependant Noumba a ceci de particulier qu'il propose un certain nombre de satellites utilisés par des partenaires, tel que SFR (sfr.noumba.net), NRJ, (mikl.noumba.net, 6-9.noumba.net) MyMajorCompany (mymajorcompany.noumba.net), MCM (mcm.noumba.net), ...

Contraintes

Des traitements asynchrones

Lorsqu'un message est posté, des traitements sont appliqués (filtrage, routage, emails, logs,...). Ces traitements ne doivent pas augmenter la latence entre l'utilisateur et le site web. Il n'est donc pas possible de les effectuer de manière synchrone, c'est à dire imposer à l'utilisateur d'attendre leur fin avant de lui rendre la main.
Si un fonctionnement synchrone est envisageable avec quelques utilisateurs en simultané, il est tout bonnement impossible pour un site à vocation grand public si l'on veut respecter une certaine qualité de service.

La solution est d'effectuer ces traitements de manière asynchrone, c'est à dire en parallèle, sans imposer à l'utilisateur leur fin pour lui rendre la main.

Les solutions

background

La première solution utilisée sur Noumba fut backgroundrb. Cet outil fournit un serveur de tâche permettant de les paralléliser dans un processus.
Si cette solution est intéressante pour quelques tâches simples, elle n'est plus possible dans le contexte lourd d'un micro-blogging, d'autant plus que backgroundrb utilisait les threads.
Les threads en Ruby sont peu efficaces (green thread) et une telle architecture consomme trop de ressources et est l'origine de bugs difficilement décelables.
Ces threads permettent d'exécuter les traitements, workers, cependant la communication entre eux n'est pas aisée ce qui complique l'enchainement des traitements.

Backgroundrb a depuis été repris et n'utilise plus à priori les threads. Malgré tout, une architecture robuste à base de file d'attente est préférable.

Hey MoM ! ou le monde des messages brokers

Les Message oriented Middleware sont des architectures qui permettent de faire communiquer des applicatifs de manière asynchrone par le biais d'une file d'attente. JMS est le MoM le plus connu et un certain nombre d'implémentations libres existent (ActiveMQ, RabbitMQ)

Parmis ceux-ci, certains implémentent le protocole texte stomp, plus simple et adapté à un site de micro-blogging. StompServer en Ruby en fait parti.

Plus de détails sur les MoM

ActiveMessaging.

Ce plugin Rails permet de communiquer vers un serveur MoM. Il lance un poller qui interroge le serveur MoM afin de lui transmettre ou lui retirer les messages.
Ce plugin est MoM agnostique, on peut interroger aussi bien un serveur ActiveMQ, StompServer et même AmazonSQS.

Noumba a utilisé un certain temps un backend StompServer / ActiveMessaging. C'est une architecture intéressante cependant l'évolution et la qualité du code de ActiveMessaging sont à surveiller de prêt.

Noumba en tant que micro-blog génère une forte charge. Or cette charge devient vite un handicap pour le bon fonctionnement du poller.
La conclusion qui s'impose est que Noumba se doit d'être le plus léger possible en effectuant le moins d'opération même par le biais d'un plugin.

Que REST il ?

REST est en effet la solution la plus simple, la plus standard (HTTP) et la moins lourde.
Dans sa dernière architecture, Noumba communique en REST avec un backend, le Hub, également en Rails. Les messages sous forme de Hash sont sérialisés puis transmis au backend.
Cependant il est toujours nécessaire d'implémenter une architecture MoM cà´té Hub afin d'obtenir un fonctionnement asynchrones.

XMPP bien sûr !

Quel serveur robuste fonctionne de fait sous forme de file d'attente, tout en étant robuste et utilisant un protocole standard, connu et ouvert ? XMPP bien sûr !
Ejabberd est un des serveurs Jabber le plus robuste. Etant en erlang, il peut facilement être réparti sous forme de cluster si le besoin se fait sentir.

Entre REST et XMPP il nous manque le lien Ruby on Rails. ActionMessenger vient le combler. Ce plugin Rails permet de transmettre des messages XMPP en utilisant un compte Jabber. Il fonctionne simplement à la manière d'ActionMailer.

Le Hub implémente ce plugin. Il reçoit les objets sérialisés et les transmet à divers comptes Jabber puis répond aussità´t à Noumba au travers de son API REST.

Click to continue reading

Creative Commons License
This work is licensed under a Creative Commons Attribution 2.0 License.