<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -21,6 +21,8 @@
 #  last_login_ip       :string(255)
 #  stylesheet          :string(255)
 #  old_password        :string(20)
+#  karma               :integer(4)      default(20), not null
+#  nb_votes            :integer(4)      default(0), not null
 #  created_at          :datetime
 #  updated_at          :datetime
 #
@@ -37,13 +39,13 @@ class Account &lt; ActiveRecord::Base
 
   validates_presence_of :login, :message =&gt; &quot;Veuillez choisir un pseudo&quot;
   validates_presence_of :email, :message =&gt; &quot;Veuillez entrer votre adresse email&quot;
-  validates_uniqueness_of :email, :case_sensitive =&gt; false, :message =&gt; &quot;Cette adresse email est d&#233;j&#224; utilis&#233;e pour un compte LinuxFr.org&quot;
 
 ### Authentication ###
 
   acts_as_authentic do |config|
     config.validates_length_of_login_field_options :within =&gt; 3..30, :message =&gt; &quot;Le login doit faire au moins 3 caract&#232;res, et pas plus de 30 caract&#232;res&quot;
     config.validates_uniqueness_of_login_field_options :case_sensitive =&gt; true, :message =&gt; &quot;Ce login est d&#233;j&#224; utilis&#233;, veuillez en choisir un autre&quot;
+    config.validates_uniqueness_of_email_field_options :case_sensitive =&gt; true, :message =&gt; &quot;Cette adresse email est d&#233;j&#224; utilis&#233;e pour un compte LinuxFr.org&quot;
     config.perishable_token_valid_for 24.hours
   end
 
@@ -97,6 +99,25 @@ class Account &lt; ActiveRecord::Base
     user.reactivate!
   end
 
+### Karma ###
+
+  def daily_karma
+    self.karma -= Vote.count(:conditions =&gt; [&quot;nodes.user_id = ? AND (votes.created_at BETWEEN ? AND ?) AND vote = 0&quot;,
+                                             self.id, DateTime.yesterday.beginning_of_day, DateTime.yesterday.end_of_day],
+                             :joins =&gt; :node).to_i
+    self.karma += Vote.count(:conditions =&gt; [&quot;nodes.user_id = ? AND (votes.created_at BETWEEN ? AND ?) AND vote = 1&quot;,
+                                             self.id, DateTime.yesterday.beginning_of_day, DateTime.yesterday.end_of_day],
+                             :joins =&gt; :node).to_i
+    self.karma -= Relevance.count(:conditions =&gt; [&quot;comments.user_id = ? AND (relevances.created_at BETWEEN ? AND ?) AND vote = 0&quot;,
+                                                  self.id, DateTime.yesterday.beginning_of_day, DateTime.yesterday.end_of_day],
+                                  :joins =&gt; :comment).to_i
+    self.karma += Relevance.count(:conditions =&gt; [&quot;comments.user_id = ? AND (relevances.created_at BETWEEN ? AND ?) AND vote = 1&quot;,
+                                                  self.id, DateTime.yesterday.beginning_of_day, DateTime.yesterday.end_of_day],
+                                  :joins =&gt; :comment).to_i
+    self.nb_votes = 3 + karma / 10
+    save
+  end
+
 ### Presentation ###
 
   def email_address</diff>
      <filename>app/models/account.rb</filename>
    </modified>
    <modified>
      <diff>@@ -100,6 +100,12 @@ class Comment &lt; ActiveRecord::Base
 
 ### Calculations ###
 
+  before_create :default_score
+
+  def default_score
+    self.score = Math.log10(user.account.karma).to_i - 1
+  end
+
   def nb_answers
     self.class.published.descendants(materialized_path).count
   end
@@ -129,6 +135,7 @@ class Comment &lt; ActiveRecord::Base
   def votable_by?(user)
     user &amp;&amp; !deleted? &amp;&amp; self.user != user &amp;&amp;
         (Time.now - created_at) &lt; 3.months &amp;&amp;
+        user.account.nb_votes &gt; 0          &amp;&amp;
         !user.relevances.exists?(:comment_id =&gt; id)
   end
 </diff>
      <filename>app/models/comment.rb</filename>
    </modified>
    <modified>
      <diff>@@ -37,6 +37,7 @@ class Content &lt; ActiveRecord::Base
   def votable_by?(user)
     user &amp;&amp; !deleted? &amp;&amp; self.user != user &amp;&amp;
         (Time.now - created_at) &lt; 3.months &amp;&amp;
+        user.account.nb_votes &gt; 0          &amp;&amp;
         !user.votes.exists?(:node_id =&gt; node.id)
   end
 </diff>
      <filename>app/models/content.rb</filename>
    </modified>
    <modified>
      <diff>@@ -24,12 +24,14 @@ class Relevance &lt; ActiveRecord::Base
 
   # An user can vote for a comment...
   def self.for(user, comment)
+    Account.decrement_counter(:nb_votes, user.account.id)
     user.relevances.create(:comment_id =&gt; comment.id, :vote =&gt; true)
     Comment.increment_counter(:score, comment.id)
   end
 
   # ...or he can vote against it
   def self.against(user, comment)
+    Account.decrement_counter(:nb_votes, user.account.id)
     user.relevances.create(:comment_id =&gt; comment.id, :vote =&gt; false)
     Comment.decrement_counter(:score, comment.id)
   end</diff>
      <filename>app/models/relevance.rb</filename>
    </modified>
    <modified>
      <diff>@@ -27,6 +27,7 @@ class Vote &lt; ActiveRecord::Base
 
   # An user can vote for a node...
   def self.for(user, node)
+    Account.decrement_counter(:nb_votes, user.account.id)
     cancel(user, node)
     user.votes.create(:node_id =&gt; node.id, :vote =&gt; true)
     Node.increment_counter(:score, node.id)
@@ -35,6 +36,7 @@ class Vote &lt; ActiveRecord::Base
 
   # ...or he can vote against it
   def self.against(user, node)
+    Account.decrement_counter(:nb_votes, user.account.id)
     cancel(user, node)
     user.votes.create(:node_id =&gt; node.id, :vote =&gt; false)
     Node.decrement_counter(:score, node.id)</diff>
      <filename>app/models/vote.rb</filename>
    </modified>
    <modified>
      <diff>@@ -48,6 +48,7 @@
           = image_tag 'icones/lock-insecure.png', :alt =&gt; &quot;Acc&#232;s en clair (http)&quot;, :class =&gt; &quot;access&quot;
         - if current_user
           %h1= current_user.name
+          %p Il vous reste #{current_user.account.nb_votes} avis
           %p= link_to &quot;Proposer un contenu&quot;, '/proposer_un_contenu'
           %p= link_to &quot;Mon tableau de bord&quot;, dashboard_path
           %p= link_to &quot;Modifier mes pr&#233;f&#233;rences&quot;, edit_account_path</diff>
      <filename>app/views/layouts/application.html.haml</filename>
    </modified>
    <modified>
      <diff>@@ -7,6 +7,7 @@ class CreateVotes &lt; ActiveRecord::Migration
       t.datetime :created_at
     end
     add_index :votes, [:node_id, :user_id], :unique =&gt; true
+    add_index :votes, [:created_at, :vote, :node_id]
   end
 
   def self.down</diff>
      <filename>db/migrate/20090130001540_create_votes.rb</filename>
    </modified>
    <modified>
      <diff>@@ -7,6 +7,7 @@ class CreateRelevances &lt; ActiveRecord::Migration
       t.datetime :created_at
     end
     add_index :relevances, [:comment_id, :user_id], :unique =&gt; true
+    add_index :relevances, [:created_at, :vote, :comment_id]
   end
 
   def self.down</diff>
      <filename>db/migrate/20090205000452_create_relevances.rb</filename>
    </modified>
    <modified>
      <diff>@@ -17,6 +17,8 @@ class CreateAccounts &lt; ActiveRecord::Migration
       t.datetime :last_login_at
       t.string   :current_login_ip
       t.string   :last_login_ip
+      t.integer  :karma,                :null =&gt; false, :default =&gt; 20
+      t.integer  :nb_votes,             :null =&gt; false, :default =&gt; 0
       t.string   :stylesheet
       t.string   :old_password, :limit =&gt; 20
       t.timestamps
@@ -29,6 +31,11 @@ class CreateAccounts &lt; ActiveRecord::Migration
     execute &quot;ALTER TABLE `accounts` MODIFY COLUMN `perishable_token` VARCHAR(255) BINARY CHARACTER SET latin1 COLLATE latin1_bin NOT NULL&quot;
 
     add_index :accounts, :user_id
+    add_index :accounts, :login
+    add_index :accounts, :email
+    add_index :accounts, :persistence_token
+    add_index :accounts, :single_access_token
+    add_index :accounts, :perishable_token
   end
 
   def self.down</diff>
      <filename>db/migrate/20090505233940_create_accounts.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,6 +1,7 @@
 namespace :linuxfr do
   desc &quot;Daily crontab&quot;
   task :daily =&gt; [
+    :daily_karma,
     :flush_poll_ips,
     :delete_old_passive_accounts,
     :delete_old_boards,
@@ -9,6 +10,11 @@ namespace :linuxfr do
     'friendly_id:remove_old_slugs'
   ]
 
+  desc &quot;New day =&gt; update karma and give new votes&quot;
+  task :daily_karma =&gt; :environment do
+    Account.active.find_each {|a| a.daily_karma }
+  end
+
   desc &quot;New day =&gt; the users can revote on polls&quot;
   task :flush_poll_ips =&gt; :environment do
     PollIp.delete_all</diff>
      <filename>lib/tasks/linuxfr.rake</filename>
    </modified>
    <modified>
      <diff>@@ -23,6 +23,8 @@
 #  old_password        :string(20)
 #  created_at          :datetime
 #  updated_at          :datetime
+#  karma               :integer(4)      default(20), not null
+#  nb_votes            :integer(4)      default(0), not null
 #
 
 # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html</diff>
      <filename>test/fixtures/accounts.yml</filename>
    </modified>
    <modified>
      <diff>@@ -23,6 +23,8 @@
 #  old_password        :string(20)
 #  created_at          :datetime
 #  updated_at          :datetime
+#  karma               :integer(4)      default(20), not null
+#  nb_votes            :integer(4)      default(0), not null
 #
 
 require 'test_helper'</diff>
      <filename>test/unit/account_test.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>30f8362ae71e83c28d36f9dafef26fb215a6258c</id>
    </parent>
  </parents>
  <author>
    <name>Bruno Michel</name>
    <email>bmichel@menfin.info</email>
  </author>
  <url>http://github.com/nono/linuxfr.org/commit/649632b27a53395a9fb492c4bfcdf43c44c42c2d</url>
  <id>649632b27a53395a9fb492c4bfcdf43c44c42c2d</id>
  <committed-date>2009-11-06T16:44:16-08:00</committed-date>
  <authored-date>2009-11-06T16:44:16-08:00</authored-date>
  <message>Users karma and nb votes</message>
  <tree>3cf36ac8c00d04504869204e7690e9d448a1988a</tree>
  <committer>
    <name>Bruno Michel</name>
    <email>bmichel@menfin.info</email>
  </committer>
</commit>
