<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -8,9 +8,9 @@ require 'merb-core/test/tasks/spectasks'
 NAME = &quot;blog-slice&quot;
 AUTHOR = &quot;Maxime Guilbot for Ekohe&quot;
 EMAIL = &quot;maxime@ekohe.com&quot;
-HOMEPAGE = &quot;http://merbivore.com/&quot;
+HOMEPAGE = &quot;http://ekohe.com/&quot;
 SUMMARY = &quot;Blog Slice is a very basic blogging system&quot;
-GEM_VERSION = &quot;0.9.10&quot;
+GEM_VERSION = &quot;1.0.10&quot;
 
 spec = Gem::Specification.new do |s|
   s.rubyforge_project = 'merb'
@@ -24,7 +24,7 @@ spec = Gem::Specification.new do |s|
   s.author = AUTHOR
   s.email = EMAIL
   s.homepage = HOMEPAGE
-  s.add_dependency('merb-slices', '&gt;= 0.9.10')
+  s.add_dependency('merb-slices', '&gt;= 1.0.10')
   s.require_path = 'lib'
   s.files = %w(LICENSE README Rakefile TODO) + Dir.glob(&quot;{lib,spec,app,public,stubs}/**/*&quot;)
 end</diff>
      <filename>Rakefile</filename>
    </modified>
    <modified>
      <diff>@@ -1,3 +1,5 @@
+require &quot;xmlrpc/server&quot;
+
 class BlogSlice::Posts &lt; BlogSlice::Application
   provides :html, :xml, :rss
   before :authorization_required, :exclude =&gt; [:index, :show, :feed, :trackback]
@@ -26,6 +28,11 @@ class BlogSlice::Posts &lt; BlogSlice::Application
   end
   
   def show
+    # This is a pingback-enabled resource, so we return the X-Pingback header
+    self.headers.merge!({'X-Pingback' =&gt; (blog_options[:host] + slice_url(:pingback))})
+
+    return &quot;&quot; if request.method == :head
+    
     # Increase view count
     @post.update_attributes(:views_count =&gt; ((@post.views_count || 0) + 1))
     
@@ -87,6 +94,47 @@ class BlogSlice::Posts &lt; BlogSlice::Application
     end
   end
   
+  def pingback
+    xmlrpc = XMLRPC::BasicServer.new
+
+    xmlrpc.add_handler(&quot;pingback.ping&quot;) do |source_url, target_url|
+      Linkback.new(:source_url =&gt; source_url, :target_url =&gt; target_url, :type =&gt; 'linkback').handle_linkback
+    end
+    puts self.request.inspect
+    
+    xml_response = xmlrpc.process(request.raw_post)
+
+    # Log the error if there is one
+    parser = XMLRPC::XMLParser::XMLStreamParser.new
+    ret = parser.parseMethodResponse(xml_response)
+    Merb.logger.info(&quot;XMLRPC fault raised. Code: #{ret[1].faultCode}: Message: #{ret[1].faultString}&quot;) unless ret[0]
+
+    self.headers[&quot;Content-Type&quot;] = &quot;text/xml; charset=utf-8&quot;
+
+    render xml_response, :layout =&gt; false
+
+    # answer = &lt;&lt;-ANSWER
+    #   &lt;?xml version=&quot;1.0&quot;?&gt;
+    #   &lt;methodResponse&gt;
+    #     &lt;fault&gt;
+    #       &lt;value&gt;
+    #         &lt;struct&gt;
+    #           &lt;member&gt;
+    #             &lt;name&gt;faultCode&lt;/name&gt;
+    #             &lt;value&gt;&lt;int&gt;0&lt;/int&gt;&lt;/value&gt;
+    #           &lt;/member&gt;
+    #           &lt;member&gt;
+    #             &lt;name&gt;faultString&lt;/name&gt;
+    #             &lt;value&gt;&lt;string&gt;Too many parameters.&lt;/string&gt;&lt;/value&gt;
+    #           &lt;/member&gt;
+    #         &lt;/struct&gt;
+    #       &lt;/value&gt;
+    #     &lt;/fault&gt;
+    #   &lt;/methodResponse&gt;
+    # ANSWER
+    # render answer
+  end
+  
   protected
   
   def get_post</diff>
      <filename>app/controllers/posts.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,3 +1,6 @@
+require 'hpricot'
+require 'open-uri'
+
 class Linkback
   include DataMapper::Resource
   include DataMapper::Timestamp
@@ -25,4 +28,23 @@ class Linkback
   def outgoing?
     self.direction == true
   end
+  
+  def handle_linkback
+    begin
+      #source_html = open(source_uri) if source_uri =~ /^http:\/\//
+      #@parser     = Hpricot(source_html)
+
+      self.title  = &quot;bla&quot; # FIXME
+      #return 17 unless @linking_node = find_linking_node_to(target_uri)
+      #@excerpt = excerpt_content_to(@linking_node, target_uri)
+      self.excerpt = &quot;bla&quot; # FIXME
+      self.save
+      #return 33 unless save_pingback # invoke the outside callback.
+      return &quot;Ping from #{source_uri} to #{target_uri} registered. Thanks for linking to us.&quot;
+      ### TODO: let save_callback propagate other error codes.
+
+    rescue SocketError, OpenURI::HTTPError =&gt; e
+      return 16
+    end
+  end
 end
\ No newline at end of file</diff>
      <filename>app/models/linkback.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,5 +1,6 @@
 - throw_content :head do
   %link{:rel =&gt; 'alternate', :type =&gt; 'application/rss+xml', :title =&gt; &quot;Comments RSS 2.0&quot;, :href =&gt; resource(@post, :comments, :feed)}
+  =&quot;&lt;link rel=\&quot;pingback\&quot; href=\&quot;#{(blog_options[:host] + slice_url(:pingback))}\&quot; /&gt;&quot;
 - comment_status = ((@post.comments.size == 1) ? &quot;One Comment&quot; : (((@post.comments.size==0) ? 'No' : @post.comments.size.to_s) + ' Comments'))
 
 .post{:id =&gt; &quot;post_#{@post.id}&quot;}</diff>
      <filename>app/views/posts/show.html.haml</filename>
    </modified>
    <modified>
      <diff>@@ -1,10 +1,8 @@
 - throw_content :title do
-  = link blog_options[:blog_title], :to =&gt; slice_url(:posts)
-  \/
   Tags
 
 #tags
   - @tags.each do |tag|
-    - unless tag.posts.empty?
+    - unless (tag.posts.count == 0)
       %span{:class =&gt; &quot;size_#{tag.size}&quot;}
-        = link tag.name, :to =&gt; resource(tag)
\ No newline at end of file
+        = link tag.name, :to =&gt; resource(tag), :title =&gt; pluralize('Post', tag.posts.count)
\ No newline at end of file</diff>
      <filename>app/views/tags/index.html.haml</filename>
    </modified>
    <modified>
      <diff>@@ -22,7 +22,7 @@ if defined?(Merb::Plugins)
     
     # Slice metadata
     self.description = &quot;Blog Slice is a very basic blogging system&quot;
-    self.version = &quot;0.9.10&quot;
+    self.version = &quot;0.9.11&quot;
     self.author = &quot;Maxime Guilbot for Ekohe&quot;
     
     Merb.add_mime_type :rss, nil, %w[text/xml]
@@ -74,7 +74,10 @@ if defined?(Merb::Plugins)
       end
       scope.resources :categories, :identify =&gt; :slug
       scope.resources :tags, :identify =&gt; :slug
+
+      scope.match(&quot;/posts/:slug&quot;, :method =&gt; :head).to(:controller =&gt; 'posts', :action =&gt; 'show').name(:show_post_head)
       
+      scope.match(&quot;/pingback&quot;).to(:controller =&gt; 'posts', :action =&gt; 'pingback').name(:pingback)
       scope.match(&quot;/feed&quot;).to(:controller =&gt; 'posts', :action =&gt; 'feed', :format =&gt; 'rss').name(:feed)
       scope.match(&quot;/dashboard&quot;).to(:controller =&gt; 'dashboard', :action =&gt; 'dashboard').name(:dashboard)
       scope.match(&quot;/moderate_comments&quot;).to(:controller =&gt; 'comments', :action =&gt; 'moderate').name(:moderate_comments)
@@ -110,9 +113,10 @@ if defined?(Merb::Plugins)
   dependency &quot;merb-simple-forms&quot;
   dependency &quot;RedCloth&quot;
   dependency &quot;BlueCloth&quot;
-  dependency &quot;merb_builder&quot;
+  dependency &quot;merb-builder&quot;
   dependency &quot;merb-mailer&quot;
-  require &quot;will_paginate&quot;
+  gem 'will_paginate', '~&gt; 3.0.0' 
+  require 'will_paginate'
   
   require 'blog-slice/text_rendering'
 end
\ No newline at end of file</diff>
      <filename>lib/blog-slice.rb</filename>
    </modified>
    <modified>
      <diff>@@ -14,6 +14,24 @@ namespace :slices do
     task :migrate do
     end
     
+    desc &quot;Send Pingback&quot;
+    task :send_pingback do
+      # From http://github.com/apotonick/pingback_engine/
+      require 'xmlrpc/client'
+      
+      server = XMLRPC::Client.new2(&quot;http://localhost:4000/pingback&quot;)
+
+      ok, param = server.call2(&quot;pingback.ping&quot;, ARGV[0], ARGV[1])
+
+      if ok then
+        puts &quot;Response: #{param}&quot;
+      else
+        puts &quot;Error:&quot;
+        puts param.faultCode 
+        puts param.faultString
+      end
+    end
+    
     desc &quot;Generate data&quot;
     task :generate_data =&gt; :merb_env do
       include DataMapper::Sweatshop::Unique</diff>
      <filename>lib/blog-slice/slicetasks.rb</filename>
    </modified>
    <modified>
      <diff>@@ -37,8 +37,8 @@ describe &quot;categories/index, authorized&quot; do
   it &quot;should display links for editing and destroying categories&quot; do
     @body.should have_tag(:a, :href =&gt; '/categories/anilopyrin/edit')
     @body.should have_tag(:a, :href =&gt; '/categories/colorable/edit')
-    @body.should have_tag(:a, :href =&gt; '/categories/anilopyrin', :method =&gt; :delete)
-    @body.should have_tag(:a, :href =&gt; '/categories/colorable', :method =&gt; :delete)
+    @body.should have_tag(:a, :href =&gt; '/categories/anilopyrin', :method =&gt; 'delete')
+    @body.should have_tag(:a, :href =&gt; '/categories/colorable', :method =&gt; 'delete')
   end
 end
 
@@ -80,8 +80,8 @@ describe &quot;categories/index, authorized&quot; do
   it &quot;should display links for editing and destroying categories&quot; do
     @body.should_not have_tag(:a, :href =&gt; '/categories/anilopyrin/edit')
     @body.should_not have_tag(:a, :href =&gt; '/categories/colorable/edit')
-    @body.should_not have_tag(:a, :href =&gt; '/categories/anilopyrin', :method =&gt; :delete)
-    @body.should_not have_tag(:a, :href =&gt; '/categories/colorable', :method =&gt; :delete)
+    @body.should_not have_tag(:a, :href =&gt; '/categories/anilopyrin', :method =&gt; 'delete')
+    @body.should_not have_tag(:a, :href =&gt; '/categories/colorable', :method =&gt; 'delete')
   end
 end
 </diff>
      <filename>spec/views/categories/index.html.haml_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -23,15 +23,15 @@ describe &quot;comments/form&quot; do
   end
   
   it &quot;should have a text field for the author&quot; do
-    @body.should have_tag(:input, :type =&gt; :text, :name =&gt; 'comment[author]')
+    @body.should have_tag(:input, :type =&gt; 'text', :name =&gt; 'comment[author]')
   end
   
   it &quot;should have a text field for the url&quot; do
-    @body.should have_tag(:input, :type =&gt; :text, :name =&gt; 'comment[url]')
+    @body.should have_tag(:input, :type =&gt; 'text', :name =&gt; 'comment[url]')
   end
   
   it &quot;should have a text field for the email&quot; do
-    @body.should have_tag(:input, :type =&gt; :text, :name =&gt; 'comment[email]')
+    @body.should have_tag(:input, :type =&gt; 'text', :name =&gt; 'comment[email]')
   end
   
   it &quot;should have a text area for the content&quot; do</diff>
      <filename>spec/views/comments/form.html.haml_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -26,7 +26,7 @@ describe &quot;posts/form&quot; do
   end
   
   it &quot;should have a text field for the title&quot; do
-    @body.should have_tag(:input, :type =&gt; :text, :id =&gt; 'post_title')
+    @body.should have_tag(:input, :type =&gt; 'text', :id =&gt; 'post_title')
   end
   
   it &quot;should have a text area for the content&quot; do
@@ -38,7 +38,7 @@ describe &quot;posts/form&quot; do
   end
   
   it &quot;should have a tag text field for the tags&quot; do
-    @body.should have_tag(:input, :type =&gt; :text, :id =&gt; 'post_tags_list')
+    @body.should have_tag(:input, :type =&gt; 'text', :id =&gt; 'post_tags_list')
   end
   
   it &quot;should have a multiple checkboxes for selecting categories&quot; do</diff>
      <filename>spec/views/posts/form.html.haml_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -174,5 +174,10 @@ describe &quot;posts/show not authorized&quot; do
     render
     @body.should have_tag(:a, :href =&gt; '/posts/my-first-post/trackback')
   end
+  
+  it &quot;should render the link rel='pingback' for pingback enabled resources&quot; do
+    render
+    @body.should have_tag(:link, :rel =&gt; 'pingback', :href =&gt; 'http://www.example.org/pingback')
+  end
 end
 </diff>
      <filename>spec/views/posts/show.html.haml_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -23,8 +23,6 @@ describe &quot;posts/trackback_help&quot; do
   end
   
   it &quot;should display a input textfield with the trackback url inside&quot; do
-    @body.should have_tag(&quot;input&quot;, :type =&gt; 'text') do |input|
-      input.should contain(&quot;/posts/my-first-post/trackback&quot;)
-    end
+    @body.should have_tag(&quot;input&quot;, :type =&gt; 'text', :value =&gt; &quot;http://www.example.org/posts/my-first-post/trackback&quot;)
   end
 end
\ No newline at end of file</diff>
      <filename>spec/views/posts/trackback_help.html.haml_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -13,9 +13,11 @@ describe 'tags/index' do
     @controller = BlogSlice::Tags.new(fake_request)
     
     first_tag = Tag.new(:id =&gt; 1, :slug =&gt; 'chocolate', :name =&gt; 'Chocolate')
-    first_tag.stub!(:posts).and_return([1])
+    posts = [1]
+    posts.stub!(:count).and_return(1)
+    first_tag.stub!(:posts).and_return(posts)
     second_tag = Tag.new(:id =&gt; 2, :slug =&gt; 'technology', :name =&gt; 'Technology')
-    second_tag.stub!(:posts).and_return([1])
+    second_tag.stub!(:posts).and_return(posts)
     
     @controller.instance_variable_set(:@tags, [first_tag, second_tag]) 
     </diff>
      <filename>spec/views/tags/index.html.haml_spec.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>543c48bb7da9abdbeeac5f27f1e2bbf4b096a182</id>
    </parent>
  </parents>
  <author>
    <name>Maxime Guilbot</name>
    <email>maxime@ekohe.com</email>
  </author>
  <url>http://github.com/maxime/blog-slice/commit/86a36c3494e71bc57c56987c871bf621c9e2db33</url>
  <id>86a36c3494e71bc57c56987c871bf621c9e2db33</id>
  <committed-date>2009-05-16T08:40:42-07:00</committed-date>
  <authored-date>2009-05-16T08:40:42-07:00</authored-date>
  <message>Version 0.9.11
Fixed some compatibility issues with Merb 1.0.11 and will_paginate</message>
  <tree>ee64d84f96a940bed37867de32a5c0959145f569</tree>
  <committer>
    <name>Maxime Guilbot</name>
    <email>maxime@ekohe.com</email>
  </committer>
</commit>
