<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>db/migrate/20080927224142_create_publishings.rb</filename>
    </added>
    <added>
      <filename>lib/object_extension.rb</filename>
    </added>
    <added>
      <filename>spec/models/object_spec.rb</filename>
    </added>
    <added>
      <filename>spec/models/page_version_spec.rb</filename>
    </added>
    <added>
      <filename>spec/models/publishing_spec.rb</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -7,12 +7,16 @@ class ApplicationController &lt; ActionController::Base
   filter_parameter_logging :password
   
   before_filter :initialize_page_menu
-    
+  
   def site_config(key)
     SITE_CONFIG[key.to_s]
   end
   helper_method :site_config
-    
+  
+  def append_errors_from(model, now=false)
+    now ? flash.now[:error] = model.errors.full_messages : flash[:error] = model.errors.full_messages
+  end
+  
   protected
     def page_options(options={})
       { :size =&gt; 10, :current =&gt; params[:page] }.merge(options)</diff>
      <filename>app/controllers/application.rb</filename>
    </modified>
    <modified>
      <diff>@@ -7,11 +7,20 @@ class DestinationsController &lt; ApplicationController
     @destination = Destination.new params[:destination]
   
     if @destination.save
-      flash[:success] = &quot;#{@destination.name} is now available for publishing.&quot;
+      flash[:success] = &quot;#{@destination} is now available for publishing.&quot;
       redirect_to 'index'
     else
-      flash.now[:error] = &quot;Failed to save #{@destination.name}.&quot;
+      flash.now[:error] = &quot;Failed to save #{@destination}.&quot;
       render :action =&gt; :index
     end
   end
+  
+  def destroy
+    if (@destination = Destination.find(params[:id])).destroy
+      flash[:success] = &quot;#{@destination} deleted successfully.&quot;
+    else
+      flash[:error] = &quot;Failed to delete #{@destination}.&quot;
+    end
+    redirect_to :back
+  end
 end
\ No newline at end of file</diff>
      <filename>app/controllers/destinations_controller.rb</filename>
    </modified>
    <modified>
      <diff>@@ -61,7 +61,7 @@ class PagesController &lt; ApplicationController
         format.json { render :json =&gt; { :html =&gt; @page.rendered }, :status =&gt; :ok }
       else
         format.html do
-          flash[:error] = @page.errors.full_messages
+          append_errors_from @page
           render :action =&gt; 'edit', :layout =&gt; 'pages/edit_layout.html.haml'
         end
         format.json { render :json =&gt; { :errors =&gt; @page.errors.full_messages }, :status =&gt; :unprocessable_entity }</diff>
      <filename>app/controllers/pages_controller.rb</filename>
    </modified>
    <modified>
      <diff>@@ -4,4 +4,37 @@ class PublishingsController &lt; ApplicationController
     @page = @version.page
     @publishing = Publishing.new
   end
+  
+  def create
+    page_version = Page::Version.find params[:page_version_id]
+    destinations = destination_ids? ? Destination.find(destination_ids) : []
+    destinations &lt;&lt; create_destination if create_destination?
+         
+    destinations.each do |destination|
+      destination.publishings.create :page_version =&gt; page_version
+    end
+    
+    redirect_to :back
+  end
+  
+  private
+    def create_destination
+      unless destination = Destination.create(params[:destination])
+        append_errors_from destination
+        redirect_to :back and return
+      end
+      destination
+    end
+  
+    def create_destination?
+      params[:create_destination]
+    end
+    
+    def destination_ids
+      params[:publishing].delete(:destination).reject{ |id| id.blank? }
+    end
+    
+    def destination_ids?
+      params[:publishing] &amp;&amp; params[:publishing][:destination]
+    end
 end
\ No newline at end of file</diff>
      <filename>app/controllers/publishings_controller.rb</filename>
    </modified>
    <modified>
      <diff>@@ -7,8 +7,11 @@ module ApplicationHelper
     end
   end
   
-  def action_is?(action)
-    params[:action] == action.to_sym
+  def action_is?(*actions)
+    actions.each do |action|
+      return true if params[:action] == action.to_sym
+    end
+    return false
   end
   
   def selectable_link_to(title, url, selected=false, options={})</diff>
      <filename>app/helpers/application_helper.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,7 +1,8 @@
 class Destination &lt; ActiveRecord::Base
-  has_many :publishings, :through =&gt; :page_versions do
-    def latest
-      find(:first, :order =&gt; 'publishings.created_at DESC')
+  has_many :publishings
+  has_many :page_versions, :through =&gt; :publishings do
+    def most_recently_published
+      find(:first, :include =&gt; :publishing, :order =&gt; 'publishings.created_at DESC')
     end
   end
   </diff>
      <filename>app/models/destination.rb</filename>
    </modified>
    <modified>
      <diff>@@ -28,6 +28,7 @@ class Page &lt; ActiveRecord::Base
   # force open the dynamic Page::Version class created by acts_as_versioned
   class Version &lt; ActiveRecord::Base
     has_many :code_blocks, :finder_sql =&gt; 'SELECT * FROM code_blocks WHERE code_blocks.version = #{self.version} AND code_blocks.page_id = #{self.page_id}'
+    has_many :publishings
     
     def current?
       page.version == self.version</diff>
      <filename>app/models/page.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,5 +1,29 @@
+require 'net/http'
+require 'net/https'
+require 'uri'
+
 # a Publishing is a bit of an awkward name, couldn't think of a nouny way to
 # say the act of publishing content
-class Publishing &lt; Tableless
-  attr_accessor :destination
+class Publishing &lt; ActiveRecord::Base
+  belongs_to :destination
+  belongs_to :page_version, :class_name =&gt; 'Page::Version'
+  
+  validates_presence_of :destination_id
+  validates_presence_of :page_version
+  
+  before_create :publish
+  
+  def publish
+    url = URI.parse(destination.url)
+    
+    http = Net::HTTP.new(url.host, url.port)
+    http.use_ssl = (url.scheme == 'https')
+    http.verify_mode = OpenSSL::SSL::VERIFY_NONE
+    
+    request = Net::HTTP::Post.new(url.path.blank? ? '/' : url.path)
+    request.basic_auth url.user, url.password
+    request.set_form_data(Hash[*(page_version.attributes.collect{ |k, v| [&quot;page[#{k}]&quot;, v] }.flatten)])
+    
+    http.request(request)
+  end
 end
\ No newline at end of file</diff>
      <filename>app/models/publishing.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,12 +1,12 @@
 #header
   %h1= @page
   %ul.menu
-    %li= selectable_link_to 'Versions', page_versions_path(@page), controller.is_a?(VersionsController) &amp;&amp; action_is?(:index)
-    %li= selectable_link_to 'Publish', new_page_version_publishing_path(@version), controller.is_a?(PublishingsController)
     %li= selectable_link_to 'Edit', [ :edit, @page ], controller.is_a?(PagesController) &amp;&amp; action_is?(:edit)
     %li= link_to 'Delete', @page, :method =&gt; :delete, :confirm =&gt; &quot;Are you sure you want to delete #{@page}?&quot;
 #page_content= yield
 %ul#version.menu
   %li.date= time(@version.updated_at)
+  %li= selectable_link_to 'Versions', page_versions_path(@page), controller.is_a?(VersionsController) &amp;&amp; action_is?(:index)
   %li= stateful_link_to 'Current', @page, @version.current? ? :selected : :active
   %li= stateful_link_to 'Restore', page_path(@page, :page =&gt; { :version =&gt; @version.version }), @version.current? ? :disabled : :active, :method =&gt; :put
+  %li= selectable_link_to 'Publish', new_page_version_publishing_path(@version), controller.is_a?(PublishingsController)</diff>
      <filename>app/views/pages/layout.html.haml</filename>
    </modified>
    <modified>
      <diff>@@ -5,20 +5,18 @@
         %th
         %th Destination
         %th URL
-        %th Published
         %th
       - Destination.find(:all).each do |destination|
         %tr
-          %td= f.check_box :destination, :value =&gt; destination.id
+          %td= f.check_box :destination, { :name =&gt; 'publishing[destination][]' }, destination.id, nil
           %td= destination
           %td= destination.url
-          %td= time(destinations.publishings)
           %td.actions
             = link_to 'Edit', edit_destination_path(destination)
             = link_to 'Delete', destination_path(destination), :method =&gt; 'delete', :confirm =&gt; &quot;Are you sure you want to remove #{destination} from your publishing destinations?&quot;
       - fields_for Destination.new do |d|
         %tr
-          %td= f.check_box :destination, :value =&gt; 0
+          %td= check_box_tag 'create_destination'
           %td= d.text_field :name
           %td= d.text_field :url
           %td</diff>
      <filename>app/views/publishings/new.html.haml</filename>
    </modified>
    <modified>
      <diff>@@ -1,3 +1,4 @@
 require 'labeled_form_helper_extension'
 require 'classy_forms'
 require 'association_collection'
+require 'object_extension'
\ No newline at end of file</diff>
      <filename>config/initializers/libs.rb</filename>
    </modified>
    <modified>
      <diff>@@ -73,7 +73,6 @@ CREATE TABLE destinations (
 --
 
 CREATE SEQUENCE destinations_id_seq
-    START WITH 1
     INCREMENT BY 1
     NO MAXVALUE
     NO MINVALUE
@@ -161,6 +160,37 @@ ALTER SEQUENCE pages_id_seq OWNED BY pages.id;
 
 
 --
+-- Name: publishings; Type: TABLE; Schema: public; Owner: -; Tablespace: 
+--
+
+CREATE TABLE publishings (
+    id integer NOT NULL,
+    destination_id integer,
+    page_version_id integer,
+    created_at timestamp without time zone
+);
+
+
+--
+-- Name: publishings_id_seq; Type: SEQUENCE; Schema: public; Owner: -
+--
+
+CREATE SEQUENCE publishings_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MAXVALUE
+    NO MINVALUE
+    CACHE 1;
+
+
+--
+-- Name: publishings_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
+--
+
+ALTER SEQUENCE publishings_id_seq OWNED BY publishings.id;
+
+
+--
 -- Name: schema_migrations; Type: TABLE; Schema: public; Owner: -; Tablespace: 
 --
 
@@ -229,6 +259,13 @@ ALTER TABLE pages ALTER COLUMN id SET DEFAULT nextval('pages_id_seq'::regclass);
 -- Name: id; Type: DEFAULT; Schema: public; Owner: -
 --
 
+ALTER TABLE publishings ALTER COLUMN id SET DEFAULT nextval('publishings_id_seq'::regclass);
+
+
+--
+-- Name: id; Type: DEFAULT; Schema: public; Owner: -
+--
+
 ALTER TABLE sections ALTER COLUMN id SET DEFAULT nextval('sections_id_seq'::regclass);
 
 
@@ -265,6 +302,14 @@ ALTER TABLE ONLY pages
 
 
 --
+-- Name: publishings_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: 
+--
+
+ALTER TABLE ONLY publishings
+    ADD CONSTRAINT publishings_pkey PRIMARY KEY (id);
+
+
+--
 -- Name: sections_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: 
 --
 
@@ -322,6 +367,20 @@ CREATE INDEX index_pages_on_section_id ON pages USING btree (section_id);
 
 
 --
+-- Name: index_publishings_on_destination_id; Type: INDEX; Schema: public; Owner: -; Tablespace: 
+--
+
+CREATE INDEX index_publishings_on_destination_id ON publishings USING btree (destination_id);
+
+
+--
+-- Name: index_publishings_on_page_version_id; Type: INDEX; Schema: public; Owner: -; Tablespace: 
+--
+
+CREATE INDEX index_publishings_on_page_version_id ON publishings USING btree (page_version_id);
+
+
+--
 -- Name: unique_schema_migrations; Type: INDEX; Schema: public; Owner: -; Tablespace: 
 --
 
@@ -346,4 +405,6 @@ INSERT INTO schema_migrations (version) VALUES ('20080712230833');
 
 INSERT INTO schema_migrations (version) VALUES ('20080718040324');
 
-INSERT INTO schema_migrations (version) VALUES ('20080827084511');
\ No newline at end of file
+INSERT INTO schema_migrations (version) VALUES ('20080827084511');
+
+INSERT INTO schema_migrations (version) VALUES ('20080927224142');
\ No newline at end of file</diff>
      <filename>db/development_structure.sql</filename>
    </modified>
    <modified>
      <diff>@@ -9,7 +9,7 @@
 #
 # It's strongly recommended to check this file into your version control system.
 
-ActiveRecord::Schema.define(:version =&gt; 20080827084511) do
+ActiveRecord::Schema.define(:version =&gt; 20080927224142) do
 
   create_table &quot;code_blocks&quot;, :force =&gt; true do |t|
     t.integer  &quot;page_id&quot;
@@ -63,6 +63,15 @@ ActiveRecord::Schema.define(:version =&gt; 20080827084511) do
   add_index &quot;pages&quot;, [&quot;path&quot;], :name =&gt; &quot;index_pages_on_path&quot;
   add_index &quot;pages&quot;, [&quot;section_id&quot;], :name =&gt; &quot;index_pages_on_section_id&quot;
 
+  create_table &quot;publishings&quot;, :force =&gt; true do |t|
+    t.integer  &quot;destination_id&quot;
+    t.integer  &quot;page_version_id&quot;
+    t.datetime &quot;created_at&quot;
+  end
+
+  add_index &quot;publishings&quot;, [&quot;destination_id&quot;], :name =&gt; &quot;index_publishings_on_destination_id&quot;
+  add_index &quot;publishings&quot;, [&quot;page_version_id&quot;], :name =&gt; &quot;index_publishings_on_page_version_id&quot;
+
   create_table &quot;sections&quot;, :force =&gt; true do |t|
     t.string &quot;name&quot;
   end</diff>
      <filename>db/schema.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>d32ed9e2875b9e5201c32a7eab9fd29b56ee07d3</id>
    </parent>
  </parents>
  <author>
    <name>Ben Alavi</name>
    <email>benalavi@gmail.com</email>
  </author>
  <url>http://github.com/citrusbyte/quiki/commit/a06f83992ae37e1fea89130fe23175834e673fcd</url>
  <id>a06f83992ae37e1fea89130fe23175834e673fcd</id>
  <committed-date>2008-09-27T17:14:25-07:00</committed-date>
  <authored-date>2008-09-27T17:14:25-07:00</authored-date>
  <message>added version publishing</message>
  <tree>dfefa99113ef1f617a7cbdb07f6e4737f955a3c8</tree>
  <committer>
    <name>Ben Alavi</name>
    <email>benalavi@gmail.com</email>
  </committer>
</commit>
