publinator 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. data/app/controllers/publinator/application_controller.rb +7 -1
  2. data/app/controllers/publinator/manage/pages_controller.rb +92 -0
  3. data/app/controllers/publinator/manage/publishable_controller.rb +65 -29
  4. data/app/controllers/publinator/manage/sites_controller.rb +4 -4
  5. data/app/controllers/publinator/manage_controller.rb +4 -4
  6. data/app/controllers/publinator/section_controller.rb +1 -7
  7. data/app/helpers/publinator/application_helper.rb +20 -34
  8. data/app/models/publinator/asset_item.rb +9 -0
  9. data/app/models/publinator/page.rb +5 -1
  10. data/app/models/publinator/publication.rb +8 -1
  11. data/app/models/publinator/publishable_type.rb +2 -0
  12. data/app/models/publinator/section.rb +5 -1
  13. data/app/models/publinator/site.rb +3 -3
  14. data/app/views/layouts/publinator/manage.html.erb +3 -1
  15. data/app/views/publinator/manage/index.html.erb +5 -2
  16. data/app/views/publinator/manage/pages/_form.html.erb +33 -0
  17. data/app/views/publinator/manage/pages/_summary.html.erb +8 -0
  18. data/app/views/publinator/manage/pages/edit.html.erb +4 -0
  19. data/app/views/publinator/manage/pages/index.html.erb +17 -0
  20. data/app/views/publinator/manage/pages/new.html.erb +4 -0
  21. data/app/views/publinator/manage/pages/show.html.erb +16 -0
  22. data/app/views/publinator/manage/publishable/_form.html.erb +15 -7
  23. data/app/views/publinator/manage/publishable/_summary.html.erb +6 -5
  24. data/app/views/publinator/manage/publishable/index.html.erb +4 -3
  25. data/app/views/publinator/manage/publishable/show.html.erb +11 -6
  26. data/app/views/publinator/publishable/show.html.erb +1 -5
  27. data/config/initializers/paperclip.rb +4 -0
  28. data/config/routes.rb +50 -43
  29. data/db/migrate/20120725202042_create_publinator_publication_states.rb +0 -1
  30. data/db/migrate/20121011191348_create_publinator_sections.rb +1 -0
  31. data/db/migrate/20121017134533_create_publinator_pages.rb +1 -0
  32. data/db/migrate/20121020181204_create_publinator_asset_items.rb +13 -0
  33. data/lib/generators/publishable/templates/app/models/publishable_migration.rb.erb +1 -0
  34. data/lib/generators/publishable/templates/app/models/publishable_model.rb.erb +3 -3
  35. data/lib/publinator/version.rb +1 -1
  36. data/lib/publinator.rb +48 -10
  37. metadata +32 -6
@@ -1,7 +1,7 @@
1
1
  module Publinator
2
2
  class ApplicationController < ActionController::Base
3
3
  layout :current_layout
4
-
4
+ before_filter :in_a_site
5
5
  helper_method :current_site, :current_domain, :current_layout, :current_site_name
6
6
 
7
7
  def current_site_name
@@ -25,5 +25,11 @@ module Publinator
25
25
  @current_layout ||= current_site.layout
26
26
  end
27
27
  end
28
+
29
+ private
30
+
31
+ def in_a_site
32
+ raise "No site found" unless current_site.present?
33
+ end
28
34
  end
29
35
  end
@@ -0,0 +1,92 @@
1
+ require_dependency "publinator/application_controller"
2
+
3
+ module Publinator
4
+ class Manage::PagesController < Publinator::ManageController
5
+ layout "publinator/manage"
6
+
7
+ before_filter :get_pages
8
+ before_filter :get_page, :only => [:show, :edit, :update, :destroy]
9
+
10
+ def index
11
+ begin
12
+ render "manage/pages/index"
13
+ rescue ActionView::MissingTemplate
14
+ render "publinator/manage/pages/index"
15
+ end
16
+ end
17
+
18
+ def show
19
+ begin
20
+ render "manage/pages/show"
21
+ rescue ActionView::MissingTemplate
22
+ render "publinator/manage/pages/show"
23
+ end
24
+ end
25
+
26
+ def new
27
+ @page = Publinator::Page.send(:new, {
28
+ :publication => Publinator::Publication.new(
29
+ :publish_at => 1.day.from_now.beginning_of_day + 8.hours,
30
+ :archive_at => 31.days.from_now.beginning_of_day,
31
+ :site => current_site,
32
+ :publishable_type => "Publinator::Page"
33
+ )
34
+ })
35
+ @page.asset_items.build
36
+ @field_names = @page.editable_fields.collect{ |an| an.to_sym }
37
+ begin
38
+ render "manage/pages/new"
39
+ rescue ActionView::MissingTemplate
40
+ render "publinator/manage/pages/new"
41
+ end
42
+ end
43
+
44
+ def edit
45
+ @field_names = @page.editable_fields.collect{ |an| an.to_sym }
46
+ @page.asset_items.build
47
+ begin
48
+ render "manage/pages/edit"
49
+ rescue ActionView::MissingTemplate
50
+ render "publinator/manage/pages/edit"
51
+ end
52
+ end
53
+
54
+ def create
55
+ @page = Publinator::Page.new(params[:page])
56
+ @page.site = current_site
57
+ if @page.save
58
+ redirect_to "/manage/pages", :notice => "Page created."
59
+ else
60
+ begin
61
+ render "manage/pages/new", :notice => "Page could not be created."
62
+ rescue ActionView::MissingTemplate
63
+ render "publinator/manage/pages/new", :notice => "Page could not be created."
64
+ end
65
+ end
66
+ end
67
+
68
+ def update
69
+ @page.update_attributes(params[:page])
70
+ @page.site = current_site
71
+ if @page.save
72
+ redirect_to "/manage/pages", :notice => "Page updated."
73
+ else
74
+ begin
75
+ render "manage/page/edit", :notice => "Page could not be updated."
76
+ rescue ActionView::MissingTemplate
77
+ render "publinator/manage/pages/edit", :notice => "Page could not be updated."
78
+ end
79
+ end
80
+ end
81
+
82
+ private
83
+
84
+ def get_pages
85
+ @pages = Publinator::Page.where(:site_id => current_site.id).order("updated_at desc")
86
+ end
87
+
88
+ def get_page
89
+ @page = @pages.find(params[:id])
90
+ end
91
+ end
92
+ end
@@ -4,74 +4,110 @@ module Publinator
4
4
  class Manage::PublishableController < ApplicationController
5
5
  layout "publinator/manage"
6
6
 
7
+ before_filter :get_publishable
8
+
7
9
  def index
8
- @publishables = Publinator::Publication.for_site(current_site.id).where(:publishable_type => params["publishable_type"].singularize.capitalize).order("updated_at desc")
9
10
  begin
10
- render "manage/#{params[:publishable_type]}/index"
11
+ render "manage/#{@publishable_collection_name}/index"
11
12
  rescue ActionView::MissingTemplate
12
13
  render "publinator/manage/publishable/index"
13
14
  end
14
15
  end
15
16
 
16
17
  def show
17
- @publication = Publinator::Publication.find_by_publishable_type_and_slug(params[:publishable_type].singularize.capitalize, params[:id])
18
- @publishable = @publication.publishable_type.singularize.capitalize.constantize.send(:find, @publication.publishable_id)
19
18
  begin
20
- render "#{params[:publishable_type]}/show"
19
+ render "manage/#{@publishable_collection_name}/show"
21
20
  rescue ActionView::MissingTemplate
22
21
  render "publinator/manage/publishable/show"
23
22
  end
24
23
  end
25
24
 
26
25
  def new
27
- publishable_class = params['publishable_type'].singularize.capitalize.constantize
28
- #@publication = Publinator::Publication.find_by_publishable_type_and_publishable_id(params[:publishable_type].singularize.capitalize, params[:id])
29
- @publishable = publishable_class.send(:new, {
26
+ @publishable = @publishable_class.new(
30
27
  :publication => Publinator::Publication.new(
31
- :publish_at => 1.day.from_now.beginning_of_day + 8.hours,
32
- :archive_at => 31.days.from_now.beginning_of_day,
33
- :site_id => current_site.id,
34
- :publishable_type => params['publishable_type'].singularize.capitalize
28
+ :publish_at => 1.day.from_now.beginning_of_day + 8.hours,
29
+ :archive_at => 31.days.from_now.beginning_of_day,
30
+ :site => current_site,
31
+ :publishable_type => @publishable_type.name
35
32
  )
36
- })
37
- @field_names = (publishable_class.attribute_names - ["id", "created_at", "updated_at"]).collect{ |an| an.to_sym }
33
+ )
34
+ @publishable.asset_items.build
35
+ @field_names = @publishable.editable_fields.collect{ |an| an.to_sym }
38
36
  begin
39
- render "#{params[:publishable_type]}/new"
37
+ render "manage/#{@publishable_collection_name}/new"
40
38
  rescue ActionView::MissingTemplate
41
39
  render "publinator/manage/publishable/new"
42
40
  end
43
41
  end
44
42
 
45
43
  def edit
46
- @publication = Publinator::Publication.find_by_publishable_type_and_slug(params[:publishable_type].singularize.capitalize, params[:id])
47
- @publishable = @publication.publishable_type.singularize.capitalize.constantize.send(:find, @publication.publishable_id)
44
+ @publishable.asset_items.build
45
+
48
46
  begin
49
- render "#{params[:publishable_type]}/edit"
47
+ render "manage/#{@publishable_collection_name}/edit"
50
48
  rescue ActionView::MissingTemplate
51
49
  render "publinator/manage/publishable/edit"
52
50
  end
53
51
  end
54
52
 
55
53
  def create
56
- @publishable_type = PublishableType.find_by_name(params['publishable_type'].singularize.capitalize)
57
- @publishable_class = @publishable_type.name.capitalize.constantize
58
- publishable_params = params[@publishable_type.name.downcase.to_sym]
59
- publication_params = publishable_params.delete('publication').merge({ :site_id => current_site.id, :publishable_type => @publishable_type.name.capitalize })
60
- publication_params.merge({:section_id => publishable_params[:section_id]}) if publishable_params[:section_id]
61
- @publication = Publinator::Publication.create!(publication_params)
62
- @publishable = @publishable_type.name.capitalize.constantize.send(:new, publishable_params, :publication => @publication)
54
+ @publishable = @publishable_class.new(params[@publishable_member_name.to_sym])
55
+ logger.info current_site.to_yaml
56
+ @publishable.publication.site = current_site
63
57
 
64
58
  if @publishable.save
65
- @publication.publishable_id = @publishable.id
66
- @publication.save
67
- redirect_to "/manage/#{params[:publishable_type]}", :notice => "#{@publishable_type.name} created."
59
+ redirect_to "/manage/#{@publishable_collection_name}", :notice => "#{@publishable_type.name} created."
68
60
  else
69
61
  begin
70
- render "#{params[:publishable_type]}/new", :notice => "#{@publishable_type.name} could not be created."
62
+ render "#{@publishable_collection_name}/new", :notice => "#{@publishable_type.name} could not be created."
71
63
  rescue ActionView::MissingTemplate
72
64
  render "publinator/manage/publishable/new", :notice => "#{@publishable_type.name} could not be created."
73
65
  end
74
66
  end
75
67
  end
68
+
69
+ def update
70
+ if @publishable_class.send(:update, @publishable.id, params[@publishable_class_name.downcase.to_sym])
71
+ redirect_to "/manage/#{@publishable_collection_name}", :notice => "#{@publishable_type.name} updated."
72
+ else
73
+ begin
74
+ render "#{@publishable_collection_name}/edit", :notice => "#{@publishable_type.name} could not be updated."
75
+ rescue ActionView::MissingTemplate
76
+ render "publinator/manage/publishable/edit", :notice => "#{@publishable_type.name} could not be updated."
77
+ end
78
+ end
79
+ end
80
+
81
+ private
82
+
83
+ def get_publishable
84
+ if params["publishable_type"].nil?
85
+ @publishable_class_name = "Page"
86
+ @publishable_collection_name = "pages"
87
+ @publishable_class = Publinator::Page
88
+ @publishable_type = PublishableType.find_by_name("Publinator::Page")
89
+ @publishable_type_name = @publishable_type.name
90
+ else
91
+ @publishable_class_name = params["publishable_type"].singularize.capitalize
92
+ @publishable_collection_name = params["publishable_type"]
93
+ @publishable_member_name = @publishable_class_name.downcase
94
+ @publishable_class = @publishable_class_name.constantize
95
+ @publishable_type = PublishableType.find_by_name(params['publishable_type'].singularize.capitalize)
96
+ @publishable_type_name = @publishable_type.name
97
+ end
98
+
99
+ @publications = Publinator::Publication.for_site(current_site.id).where(:publishable_type => @publishable_type.name).order("updated_at desc")
100
+ @publishables = @publications.collect{ |pub| pub.publishable }
101
+ if params[:id]
102
+ original_id = params[:id]
103
+ if original_id.to_i.to_s == params[:id]
104
+ @publishable = @publishable_class.send(:find, params[:id])
105
+ @publication = @publishable.publication
106
+ else
107
+ @publication = @publications.find(:first, :conditions => ["slug = ?", params[:id]])
108
+ @publishable = @publication.publishable
109
+ end
110
+ end
111
+ end
76
112
  end
77
113
  end
@@ -3,15 +3,15 @@ require_dependency "publinator/application_controller"
3
3
  module Publinator
4
4
  class Manage::SitesController < ApplicationController
5
5
  layout "publinator/manage"
6
-
6
+
7
7
  def index
8
8
  @sites = Publinator::Site.all
9
9
  end
10
-
10
+
11
11
  def new
12
12
  @site = Publinator::Site.new
13
13
  end
14
-
14
+
15
15
  def create
16
16
  @site = Publinator::Site.new(params[:site])
17
17
  if @site.save
@@ -21,4 +21,4 @@ module Publinator
21
21
  end
22
22
  end
23
23
  end
24
- end
24
+ end
@@ -1,13 +1,13 @@
1
1
  class Publinator::ManageController < Publinator::ApplicationController
2
2
  layout 'publinator/manage'
3
3
  #before_filter :managers_only
4
-
4
+
5
5
  # def managers
6
- # if
6
+ # if
7
7
  # end
8
-
8
+
9
9
  def index
10
10
  @publishable_types = Publinator::PublishableType.all
11
11
  render "publinator/manage/index"
12
12
  end
13
- end
13
+ end
@@ -5,19 +5,13 @@ module Publinator
5
5
  before_filter :get_section
6
6
 
7
7
  def index
8
- logger.info "#{@section.id}"
9
8
  @publication = Publinator::Publication.find_by_section_id_and_slug(@section.id, 'index')
10
- logger.info Publication.all.collect{ |p| "/#{@section.section_slug}/#{p.slug}" }
11
- logger.info @publication.to_yaml
12
- @publishable = @publication.content
9
+ @publishable = @publication.publishable
13
10
  begin
14
11
  render "#{params[:section]}/index"
15
12
  rescue ActionView::MissingTemplate
16
13
  render "publinator/publishable/show"
17
14
  end
18
- # rescue Exception => e
19
- # logger.info e.to_yaml
20
- # redirect_to root_url, :notice => "Page not found." if @publication.nil?
21
15
  end
22
16
 
23
17
  def show
@@ -10,45 +10,31 @@ module Publinator
10
10
  RDiscount.new(markdown_text).to_html.html_safe
11
11
  end
12
12
 
13
- def menu(array)
14
- menu = content_tag(:ul, :class => 'nav_menu') do
15
- menu_content = ""
16
- array.each do |obj|
17
- menu_content += menu_item(obj)
13
+ def menu_section(title, path = "", collection)
14
+ if path.blank?
15
+ ct = "<li>#{title}<br>"
16
+ else
17
+ ct = "<li><a href='#{path}'>#{title}</a><br>"
18
+ end
19
+ if collection && collection.length && collection.length > 0
20
+ ct += "<div class='submenu'><ul>"
21
+ collection.each do |c|
22
+ ct += menu_section(c.title, c.path, c.menu_collection)
18
23
  end
19
- menu_content.html_safe
24
+ ct += "</ul></div>"
20
25
  end
21
- menu.html_safe
26
+ ct += "</li>"
27
+ ct.html_safe
22
28
  end
23
29
 
24
30
  def menu_item(obj)
25
- logger.info "ready to create entry for #{obj.class} #{obj.id}"
26
- if obj.class == Publinator::Publication
27
- logger.info "publication's publishable is #{obj.publishable.class} #{obj.publishable.id}"
28
- end
29
- raise "No publishable found for #{obj.class} #{obj.id}" if !obj.publishable
30
- tag_content = content_tag(:li) do
31
- li_content = link_to obj.publishable.title, obj.publishable.path
32
- if obj.respond_to? :publications
33
- li_content += content_tag(:div, :class => "submenu") do
34
- if obj.publications && obj.publications.length && obj.publications.length > 0
35
- submenu_content = content_tag(:ul) do
36
- sub_content = ""
37
- obj.publications.each do |pub|
38
- logger.info "ready to create entry for #{pub.publishable_type} #{pub.publishable_id} #{pub.slug}"
39
- unless pub.slug == 'index'
40
- sub_content += menu_item(pub)
41
- end
42
- end
43
- sub_content.html_safe
44
- end
45
- li_content += submenu_content
46
- end
47
- end
48
- end
49
- li_content.html_safe
50
- end
51
- tag_content
31
+ menu_section(obj.title, obj.path, obj.menu_collection)
32
+ end
33
+
34
+ def publishable_asset(pub, asset_type)
35
+ return if !pub
36
+ asset = pub.asset_file(asset_type)
37
+ image_tag asset.url if asset
52
38
  end
53
39
  end
54
40
  end
@@ -0,0 +1,9 @@
1
+ #module Publinator
2
+ class Publinator::AssetItem < ActiveRecord::Base
3
+ attr_accessible :asset, :assetable
4
+ belongs_to :assetable, :polymorphic => true
5
+ validates_presence_of :assetable
6
+
7
+ has_attached_file :asset
8
+ end
9
+ #end
@@ -2,6 +2,10 @@ module Publinator
2
2
  class Page < ActiveRecord::Base
3
3
  self.table_name = 'publinator_pages'
4
4
  acts_as_publishable
5
- attr_accessible :body, :kicker, :subtitle, :teaser, :title, :section
5
+ attr_accessible :body, :kicker, :subtitle, :teaser, :title, :section, :asset_items
6
+
7
+ def asset_types
8
+ ['header']
9
+ end
6
10
  end
7
11
  end
@@ -3,7 +3,7 @@ module Publinator
3
3
  # has_paper_trail
4
4
  attr_accessible :custom_slug, :parent_id, :publication_state_id,
5
5
  :publishable_id, :publishable_type, :slug, :publish_at,
6
- :unpublish_at, :archive_at, :section, :default, :publishable, :site
6
+ :unpublish_at, :archive_at, :section, :default, :publishable, :site, :section_id
7
7
  belongs_to :publishable, :polymorphic => true
8
8
  belongs_to :section, :class_name => "Publinator::Section"
9
9
  belongs_to :site
@@ -18,6 +18,8 @@ module Publinator
18
18
  scope :published, where(:publication_state_id => 1)
19
19
  scope :for_site, lambda { |site_id| where("site_id = ?", site_id) }
20
20
 
21
+ delegate :title, :path, :menu_collection, :to => :publishable
22
+
21
23
  def content
22
24
  publishable_type.constantize.find(publishable_id)
23
25
  end
@@ -31,6 +33,11 @@ module Publinator
31
33
  self.slug = custom_slug
32
34
  elsif publishable.present? && publishable.title.present?
33
35
  self.slug = self.publishable.title.strip.downcase.gsub(/[^a-zA-Z0-9\-\_]/, '_')
36
+ self.slug = self.slug.gsub("___", "_")
37
+ self.slug = self.slug.gsub("__", "_")
38
+ if slug.end_with?("_")
39
+ self.slug = self.slug.chop
40
+ end
34
41
  else
35
42
  self.slug = "temporary_slug_#{rand(100000)}"
36
43
  end
@@ -3,6 +3,8 @@ module Publinator
3
3
  attr_accessible :name, :sluggable
4
4
 
5
5
  def self.matches?(request)
6
+ logger.info request.path_parameters
7
+ logger.info request.path_parameters[:publishable_type]
6
8
  pt = self.find_by_name(request.path_parameters[:publishable_type].singularize.capitalize)
7
9
  return pt.present?
8
10
  end
@@ -1,7 +1,7 @@
1
1
  # TODO Validate new sections - can't conflict with publishable_types
2
2
  module Publinator
3
3
  class Section < ActiveRecord::Base
4
- attr_accessible :layout, :name, :parent_id, :site, :section_slug
4
+ attr_accessible :layout, :name, :parent_id, :site, :section_slug, :position
5
5
  belongs_to :site, :class_name => "Publinator::Site"
6
6
  has_many :publications, :class_name => "Publinator::Publication"
7
7
  before_create :generate_section_slug
@@ -25,6 +25,10 @@ module Publinator
25
25
  "/#{section_slug}"
26
26
  end
27
27
 
28
+ def menu_collection
29
+ publications
30
+ end
31
+
28
32
  def publishable
29
33
  self
30
34
  end
@@ -1,9 +1,9 @@
1
1
  module Publinator
2
2
  class Site < ActiveRecord::Base
3
3
  attr_accessible :abbr, :description, :name, :parent_id, :state, :title, :default
4
- has_many :domain_names
5
- has_many :sections
6
- has_many :publications
4
+ has_many :domain_names, :class_name => "Publinator::DomainName"
5
+ has_many :sections, :class_name => "Publinator::Section"
6
+ has_many :publications, :class_name => "Publinator::Publication"
7
7
 
8
8
  # get the layout for the site
9
9
  #
@@ -10,7 +10,9 @@
10
10
  <div id="header">
11
11
  <h3><%= link_to "Managing", manage_path %> <%= link_to (current_site_name || "Publinator"), root_url, :target => "_new" %></h3>
12
12
  </div>
13
- <div id="content">
13
+ <div id="content">
14
+ <%= alert if alert %>
15
+ <%= notice if notice %>
14
16
  <%= yield %>
15
17
  </div>
16
18
  <div id="footer">
@@ -1,5 +1,8 @@
1
1
  <h2>Content Manager Home Page</h2>
2
2
 
3
+ <%= link_to "Pages", "/manage/pages" %><br>
3
4
  <% @publishable_types.each do |pt| %>
4
- <%= link_to pt.name.pluralize, "/manage/#{pt.name.downcase.pluralize}" %>
5
- <% end %>
5
+ <% unless pt.name == "Page" %>
6
+ <%= link_to pt.name.pluralize, send("manage_#{pt.name.downcase.pluralize}_path") %><br>
7
+ <% end %>
8
+ <% end %>
@@ -0,0 +1,33 @@
1
+ <%= semantic_form_for [:manage, @page], :html => { :multipart => true } do |form| %>
2
+ <% if @page.errors && @page.errors.count > 0 %>
3
+ <% @page.errors.full_messages.each do |e| %>
4
+ <%= e %><br>
5
+ <% end %>
6
+ <% end %>
7
+ <%= form.inputs "Page" do %>
8
+ <% @field_names.each do |field| %>
9
+ <%= form.input field %>
10
+ <% end %>
11
+ <% end %>
12
+ <% if @page.asset_types.length > 0 %>
13
+ <%= form.semantic_fields_for :asset_items do |asset_form| %>
14
+ <%= asset_form.inputs "Asset" do %>
15
+ <%= asset_form.input :asset_type, :as => :select, :collection => @page.asset_types %>
16
+ <%= asset_form.input :asset_file, :as => :file %>
17
+ <% end %>
18
+ <% end %>
19
+ <% end %>
20
+ <%= form.semantic_fields_for :publication do |pub| %>
21
+ <%= pub.inputs "Publication Settings" do %>
22
+ <%= pub.input :custom_slug, :required => false %>
23
+ <%= pub.input :publish_at, :as => :datetime_select, :required => false %>
24
+ <%= pub.input :unpublish_at, :as => :datetime_select, :required => false %>
25
+ <%= pub.input :archive_at, :as => :datetime_select, :required => false %>
26
+ <%= pub.input :section, :as => :select, :required => false, :collection => current_site.sections unless current_site.sections.length == 0 %>
27
+ <% end %>
28
+ <% end %>
29
+ <%= form.actions do %>
30
+ <%= form.action :submit, :as => :button %>
31
+ <%= form.action :cancel, :as => :link %>
32
+ <% end %>
33
+ <% end %>
@@ -0,0 +1,8 @@
1
+ <tr>
2
+ <td><%= link_to summary.publication.slug, manage_page_path(summary) %></td>
3
+ <td><%= link_to summary.section.name if summary.section %></td>
4
+ <td><%= summary.updated_at %></td>
5
+ <td><%= link_to "edit", edit_manage_page_path(summary) %></td>
6
+ <td><%= link_to "show", manage_page_path(summary) %></td>
7
+ <td><%= link_to "public", summary.path %></td>
8
+ </tr>
@@ -0,0 +1,4 @@
1
+ <h2>Edit Page <%= @page.publication.slug %></h2>
2
+
3
+ <%= render :partial => "form" %>
4
+
@@ -0,0 +1,17 @@
1
+ <h2>Pages</h2>
2
+
3
+ <table id="publishables">
4
+ <thead>
5
+ <tr>
6
+ <th>Page Title</th>
7
+ <th>Section</th>
8
+ <th>Last Updated At</th>
9
+ <th>Edit</th>
10
+ <th>Show</th>
11
+ <th>Public Link</th>
12
+ </tr>
13
+ </thead>
14
+ <%= render :collection => @pages, :partial => "summary" %>
15
+ </table>
16
+
17
+ <%= link_to "Add Page", "/manage/pages/new" %>
@@ -0,0 +1,4 @@
1
+ <h2>Add a new <%= @publishable.class.to_s %></h2>
2
+
3
+ <%= render :partial => "form" %>
4
+
@@ -0,0 +1,16 @@
1
+
2
+ <h1><%= @page.title %></h1>
3
+
4
+ <% @page.asset_types.each do |ai| %>
5
+ <%= image_tag @page.asset_items.where(:asset_type => ai).first.asset_file.url %>
6
+ <% end %>
7
+
8
+ <p>
9
+ <%= m(@page.body) %>
10
+ </p>
11
+
12
+ <div id="controls">
13
+ <%= link_to "Back", manage_pages_path %>
14
+ <%= link_to "Edit", edit_manage_page_path(@page) %>
15
+ <%= link_to "Delete", manage_page_path(@page), :method => :delete, :class => "danger", :confirm => "Delete this #{@publishable.class.to_s}?" %>
16
+ </div>
@@ -1,22 +1,30 @@
1
- <%= semantic_form_for @publishable, :url => manage_create_publishable_path do |form| %>
1
+ <%= semantic_form_for [:manage, @publishable], :html => { :multipart => true } do |form| %>
2
2
  <% if @publishable.errors && @publishable.errors.count > 0 %>
3
3
  <% logger.info @publishable_errors.to_yaml %>
4
- <% @publishable.errors.each do |e| %>
5
- <%= e %>
4
+ <% @publishable.errors.full_messages.each do |e| %>
5
+ <%= e %><br>
6
6
  <% end %>
7
7
  <% end %>
8
- <%= form.inputs @publishable.class.to_s do %>
9
- <% @field_names.each do |field| %>
8
+ <%= form.inputs @publishable_class.to_s do %>
9
+ <% @publishable.editable_fields.collect{ |an| an.to_sym }.each do |field| %>
10
10
  <%= form.input field %>
11
11
  <% end %>
12
12
  <% end %>
13
- <%= form.semantic_fields_for @publishable.publication do |pub| %>
13
+ <% if @publishable.asset_types.length > 0 %>
14
+ <%= form.semantic_fields_for :asset_items do |asset_form| %>
15
+ <%= asset_form.inputs "Asset" do %>
16
+ <%= asset_form.input :asset_type, :as => :select, :collection => @publishable.asset_types %>
17
+ <%= asset_form.input :asset_file, :as => :file %>
18
+ <% end %>
19
+ <% end %>
20
+ <% end %>
21
+ <%= form.semantic_fields_for :publication do |pub| %>
14
22
  <%= pub.inputs "Publication Settings" do %>
15
23
  <%= pub.input :custom_slug, :required => false %>
16
24
  <%= pub.input :publish_at, :as => :datetime_select, :required => false %>
17
25
  <%= pub.input :unpublish_at, :as => :datetime_select, :required => false %>
18
26
  <%= pub.input :archive_at, :as => :datetime_select, :required => false %>
19
- <%= pub.input :section_id, :as => :select, :required => false, :collection => current_site.sections unless current_site.sections.length == 0 %>
27
+ <%= pub.input :section, :as => :select, :required => false, :collection => current_site.sections unless current_site.sections.length == 0 %>
20
28
  <% end %>
21
29
  <% end %>
22
30
  <%= form.actions do %>
@@ -1,7 +1,8 @@
1
1
  <tr>
2
- <td><%= link_to summary.slug, manage_publishable_path(summary.publishable.class.to_s.downcase.pluralize, summary.slug) %></td>
2
+ <td><%= link_to summary.my_slug, [:manage, summary] %></td>
3
+ <td><%= link_to summary.publication.section.name if summary.publication.section %></td>
3
4
  <td><%= summary.updated_at %></td>
4
- <td><%= link_to "edit", manage_edit_publishable_path(summary.publishable.class.to_s.downcase.pluralize, summary.slug) %></td>
5
- <td><%= link_to "show", manage_publishable_path(summary.publishable.class.to_s.downcase.pluralize, summary.slug) %></td>
6
- <td><%= link_to "public", publishable_path(summary.publishable.class.to_s.downcase.pluralize, summary.slug) %></td>
7
- </tr>
5
+ <td><%= link_to "edit", send("edit_manage_#{@publishable_type_name.downcase}_path", summary) %></td>
6
+ <td><%= link_to "show", [:manage, summary] %></td>
7
+ <td><%= link_to "public", summary.path %></td>
8
+ </tr>
@@ -1,9 +1,10 @@
1
- <h2><%= params["publishable_type"].capitalize %></h2>
1
+ <h2><%= @publishable_class_name.capitalize.pluralize %></h2>
2
2
 
3
3
  <table id="publishables">
4
4
  <thead>
5
5
  <tr>
6
- <th><%= params["publishable_type"].capitalize.singularize %> Title</th>
6
+ <th><%= @publishable_class_name %> Slug</th>
7
+ <th>Section</th>
7
8
  <th>Last Updated At</th>
8
9
  <th>Edit</th>
9
10
  <th>Show</th>
@@ -13,4 +14,4 @@
13
14
  <%= render :collection => @publishables, :partial => "summary" %>
14
15
  </table>
15
16
 
16
- <%= link_to "Add #{params["publishable_type"].singularize.capitalize}", "/manage/#{params["publishable_type"]}/new" %>
17
+ <%= link_to "Add #{@publishable_class_name}", send("new_manage_#{@publishable_class_name.downcase}_path") %>
@@ -1,10 +1,15 @@
1
-
2
1
  <h1><%= @publishable.title %></h1>
3
2
 
4
- <%= @publishable.body %>
3
+ <% @publishable.asset_types.each do |ai| %>
4
+ <%= publishable_asset(@publishable, ai) %>
5
+ <% end %>
6
+
7
+ <p>
8
+ <%= m(@publishable.body) %>
9
+ </p>
5
10
 
6
11
  <div id="controls">
7
- <%= link_to "Back", manage_publishables_path(@publishable.class.to_s.downcase.pluralize) %>
8
- <%= link_to "Edit", manage_edit_publishable_path(@publishable.class.to_s.downcase.pluralize, @publishable) %>
9
- <%= link_to "Delete", manage_publishable_path(@publishable.class.to_s.downcase.pluralize, @publishable.id), :method => :delete, :class => "danger", :confirm => "Delete this #{@publishable.class.to_s}?" %>
10
- </div>
12
+ <%= link_to "Back", send("manage_#{params[:publishable_type]}_path") %>
13
+ <%= link_to "Edit", send("edit_manage_#{params[:publishable_type].singularize}_path", @publishable) %>
14
+ <%= link_to "Delete", send("manage_#{params[:publishable_type].singularize}_path", @publishable), :method => :delete, :class => "danger", :confirm => "Delete this #{@publishable.class.to_s}?" %>
15
+ </div>
@@ -1,5 +1 @@
1
- <h1>
2
- <%= @publishable.title %>
3
- </h1>
4
-
5
- <%= m(@publishable.body) %>
1
+ <%= m(@publishable.body) %>
@@ -0,0 +1,4 @@
1
+ Paperclip::Attachment.default_options.merge!(
2
+ :storage => :s3,
3
+ :path => ":attachment/#{Rails.env}/:id/:style.:extension")
4
+
data/config/routes.rb CHANGED
@@ -1,37 +1,54 @@
1
1
  Publinator::Engine.routes.draw do
2
2
 
3
- root :to => "home#index"
4
- match '/' => 'home#index'
3
+ match "/manage" => 'manage#index'
5
4
 
6
5
  namespace :manage do
7
- match "/" => 'manage#index'
6
+
7
+ Publinator::PublishableType.all.each do |pt|
8
+ resources pt.name.pluralize.downcase.to_sym, :controller => "publishable", :publishable_type => pt.name.pluralize.downcase
9
+ #match "/#{pt.name.pluralize.downcase}" => "publishable#index", :as => pt.name.pluralize.downcase, :publishable_type => pt.name
10
+ end
11
+
12
+ #constraints(Publinator::PublishableType) do
13
+ #match '/:publishable_type/' => "publishable#index", :requirements => {
14
+ #:publishable_type => /\A([a-zA-Z]+[a-zA-Z_]*)\z/i
15
+ #}, :as => "publishables"
16
+
17
+ #match '/:publishable_type/new' => "publishable#new", :requirements => {
18
+ #:publishable_type => /\A([a-zA-Z]+[a-zA-Z_]*)\z/i
19
+ #}
20
+
21
+ #match '/:publishable_type/create' => "publishable#create", :requirements => {
22
+ #:publishable_type => /\A([a-zA-Z]+[a-zA-Z_]*)\z/i
23
+ #}, :as => "create_publishable"
24
+
25
+ #match '/:publishable_type/:id/edit' => "publishable#edit", :requirements => {
26
+ #:id => /\A\d*\z/i,
27
+ #:publishable_type => /\A([a-zA-Z]+[a-zA-Z_]*)\z/i
28
+ #}, :as => "edit_publishable"
29
+
30
+ #match '/:publishable_type/:id' => "publishable#show", :requirements => {
31
+ #:id => /\A\d*\z/i,
32
+ #:publishable_type => /\A([a-zA-Z]+[a-zA-Z_]*)\z/i
33
+ #}, :as => "publishable"
34
+ #end
35
+
36
+ resources :pages
8
37
  resources :sites
9
38
  resources :sections
10
- constraints(Publinator::PublishableType) do
11
- match '/:publishable_type/' => "publishable#index", :requirements => {
12
- :publishable_type => /\A([a-zA-Z]+[a-zA-Z_]*)\z/i
13
- }, :as => "publishables"
14
-
15
- match '/:publishable_type/new' => "publishable#new", :requirements => {
16
- :publishable_type => /\A([a-zA-Z]+[a-zA-Z_]*)\z/i
17
- }
18
-
19
- match '/:publishable_type/create' => "publishable#create", :requirements => {
20
- :publishable_type => /\A([a-zA-Z]+[a-zA-Z_]*)\z/i
21
- }, :as => "create_publishable"
22
-
23
- match '/:publishable_type/:id/edit' => "publishable#edit", :requirements => {
24
- :id => /\A\d*\z/i,
25
- :publishable_type => /\A([a-zA-Z]+[a-zA-Z_]*)\z/i
26
- }, :as => "edit_publishable"
27
-
28
- match '/:publishable_type/:id' => "publishable#show", :requirements => {
29
- :id => /\A\d*\z/i,
30
- :publishable_type => /\A([a-zA-Z]+[a-zA-Z_]*)\z/i
31
- }, :as => "publishable"
32
- end
33
39
  end
34
40
 
41
+ #constraints(Publinator::PublishableType) do
42
+ #match '/:publishable_type/' => "publishable#index", :requirements => {
43
+ #:publishable_type => /\A([a-zA-Z]+[a-zA-Z_]*)\z/i
44
+ #}
45
+
46
+ #match '/:publishable_type/:id' => "publishable#show", :requirements => {
47
+ #:id => /\A\d*\z/i,
48
+ #:publishable_type => /\A([a-zA-Z]+[a-zA-Z_]*)\z/i
49
+ #}, :as => "publishable"
50
+ #end
51
+
35
52
  constraints(Publinator::Section) do
36
53
  match '/:section/' => "section#index", :requirements => {
37
54
  :section => /\A([a-zA-Z0-9]+[a-zA-Z0-9\-_]*)\z/i
@@ -43,26 +60,16 @@ Publinator::Engine.routes.draw do
43
60
  }, :as => "publishable"
44
61
  end
45
62
 
63
+ match "/:slug", :controller => :home, :action => :page, :requirements => {
64
+ :slug => /\A([a-zA-Z]+[a-zA-Z\-_]*)\z/i
65
+ }, :as => 'publishable'
46
66
 
47
- constraints(Publinator::PublishableType) do
48
- match '/:publishable_type/' => "publishable#index", :requirements => {
49
- :publishable_type => /\A([a-zA-Z]+[a-zA-Z_]*)\z/i
50
- }
51
-
52
- match '/:publishable_type/:id' => "publishable#show", :requirements => {
53
- :id => /\A\d*\z/i,
54
- :publishable_type => /\A([a-zA-Z]+[a-zA-Z_]*)\z/i
55
- }, :as => "publishable"
67
+ Publinator::PublishableType.all.each do |pt|
68
+ resources pt.name.pluralize.downcase.to_sym, :controller => "publishable", :only => [:index, :show]
56
69
  end
57
70
 
58
- match "/:section/:slug", :controller => :sections, :action => :page, :requirements => {
59
- :section => /\A([a-zA-Z0-9]+[a-zA-Z0-9\-_]*)\z/i,
60
- :slug => /\A([a-zA-Z]+[a-zA-Z\-_]*)\z/i
61
- }
62
-
63
71
 
64
- match "/:slug", :controller => :home, :action => :page, :requirements => {
65
- :slug => /\A([a-zA-Z]+[a-zA-Z\-_]*)\z/i
66
- }
72
+ root :to => "home#index"
73
+ match '/' => 'home#index'
67
74
 
68
75
  end
@@ -3,7 +3,6 @@ class CreatePublinatorPublicationStates < ActiveRecord::Migration
3
3
  create_table :publinator_publication_states do |t|
4
4
  t.string :name, :null => false
5
5
  t.boolean :system, :default => false
6
-
7
6
  t.timestamps
8
7
  end
9
8
  Publinator::PublicationState.create(:name => "new", :system => true)
@@ -6,6 +6,7 @@ class CreatePublinatorSections < ActiveRecord::Migration
6
6
  t.boolean :layout
7
7
  t.integer :site_id
8
8
  t.string :section_slug
9
+ t.integer :position
9
10
 
10
11
  t.timestamps
11
12
  end
@@ -8,6 +8,7 @@ class CreatePublinatorPages < ActiveRecord::Migration
8
8
  t.string :teaser
9
9
  t.string :custom_slug
10
10
  t.text :body
11
+ t.integer :position
11
12
 
12
13
  t.timestamps
13
14
  end
@@ -0,0 +1,13 @@
1
+ class CreatePublinatorAssetItems < ActiveRecord::Migration
2
+ def change
3
+ create_table :publinator_asset_items do |t|
4
+ t.string :asset_type
5
+ t.references :assetable, :polymorphic => true
6
+ t.string :asset_file_name
7
+ t.string :asset_content_type
8
+ t.datetime :asset_updated_at
9
+ t.integer :asset_file_size
10
+ t.timestamps
11
+ end
12
+ end
13
+ end
@@ -4,6 +4,7 @@ class Create<%= class_name.capitalize %> < ActiveRecord::Migration
4
4
  t.string :title
5
5
  t.string :teaser
6
6
  t.text :body
7
+ t.integer :site_id
7
8
 
8
9
  # t.string :author_name
9
10
  # t.text :extra_body
@@ -1,5 +1,5 @@
1
- class <%= class_name.capitalize %> < Publinator::Publishable
2
-
1
+ class <%= class_name.capitalize %> < ActiveRecord::Base
3
2
  self.table_name = '<%= class_name.downcase.pluralize %>'
4
-
3
+ acts_as_publishable
4
+ attr_accessible :title, :body, :section
5
5
  end
@@ -1,3 +1,3 @@
1
1
  module Publinator
2
- VERSION = "0.0.6"
2
+ VERSION = "0.0.7"
3
3
  end
data/lib/publinator.rb CHANGED
@@ -4,33 +4,59 @@ module Publinator
4
4
  module ActsAsPublishable
5
5
  extend ActiveSupport::Concern
6
6
 
7
- included do
8
- end
9
-
10
7
  module ClassMethods
11
8
  def acts_as_publishable(options = {})
12
- has_one :publication,
13
- :as => :publishable,
14
- :class_name => "Publinator::Publication",
15
- :foreign_key => :publishable_id
9
+ has_one :publication,
10
+ :as => :publishable,
11
+ :class_name => "Publinator::Publication",
12
+ :foreign_key => :publishable_id
16
13
 
17
14
  accepts_nested_attributes_for :publication
18
15
  validates_presence_of :publication
19
16
  validates_associated :publication
20
17
 
18
+ has_many :asset_items,
19
+ :as => :assetable,
20
+ :class_name => "Publinator::AssetItem",
21
+ :foreign_key => :assetable_id
22
+
23
+
24
+ accepts_nested_attributes_for :asset_items, :reject_if => :all_blank
25
+
21
26
  before_validation :verify_publication
22
27
  belongs_to :site, :class_name => "Publinator::Site"
23
28
  belongs_to :section, :class_name => "Publinator::Section"
24
29
 
25
- attr_accessible :site, :publication, :section, :default
30
+ attr_accessible :site, :publication, :section, :default,
31
+ :position, :asset_items_attributes,
32
+ :custom_slug,
33
+ :publication_attributes
34
+
26
35
  attr_accessor :default
27
36
 
28
37
  scope :non_index, joins(:publication).where("publication.slug != 'index'")
29
38
  end
30
39
  end
31
40
 
41
+ def asset_types
42
+ []
43
+ end
44
+
45
+ def asset_file(asset_type_text)
46
+ publishable_asset = get_asset_by_type(asset_type_text)
47
+ publishable_asset.asset_file if publishable_asset
48
+ end
49
+
50
+ def my_slug
51
+ publication.slug
52
+ end
53
+
54
+ def asset_files
55
+ asset_types.collect{ |atype| asset_file(atype) }
56
+ end
57
+
32
58
  def editable_fields
33
- attribute_names - ["id", "created_at", "updated_at"]
59
+ attribute_names - ["id", "created_at", "updated_at", "section_id", "site_id"]
34
60
  end
35
61
 
36
62
  def path
@@ -42,15 +68,27 @@ module Publinator
42
68
  end
43
69
  end
44
70
 
71
+ def menu_collection
72
+ nil
73
+ end
74
+
45
75
  def verify_publication
46
76
  logger.info "verifying publication"
47
77
  if publication.nil?
48
78
  self.publication = Publinator::Publication.new(:publishable => self)
49
79
  end
50
- self.publication.site = site
80
+ self.publication.site = site unless publication.site.present?
51
81
  self.publication.section = section unless !section
52
82
  self.publication.default = default
53
83
  end
84
+
85
+ private
86
+
87
+ def get_asset_by_type(asset_type_text)
88
+ all_of_asset_type = asset_items.where(:asset_type => asset_type_text)
89
+ all_of_asset_type.first if all_of_asset_type && all_of_asset_type.length
90
+ end
91
+
54
92
  end
55
93
  end
56
94
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: publinator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.7
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-10-19 00:00:00.000000000 Z
12
+ date: 2012-10-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -18,7 +18,7 @@ dependencies:
18
18
  requirements:
19
19
  - - ~>
20
20
  - !ruby/object:Gem::Version
21
- version: 3.2.1
21
+ version: 3.2.8
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
@@ -26,7 +26,7 @@ dependencies:
26
26
  requirements:
27
27
  - - ~>
28
28
  - !ruby/object:Gem::Version
29
- version: 3.2.1
29
+ version: 3.2.8
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: transitions
32
32
  requirement: !ruby/object:Gem::Requirement
@@ -123,6 +123,22 @@ dependencies:
123
123
  - - ! '>='
124
124
  - !ruby/object:Gem::Version
125
125
  version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: paperclip
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ~>
132
+ - !ruby/object:Gem::Version
133
+ version: '3.0'
134
+ type: :runtime
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ~>
140
+ - !ruby/object:Gem::Version
141
+ version: '3.0'
126
142
  - !ruby/object:Gem::Dependency
127
143
  name: sqlite3
128
144
  requirement: !ruby/object:Gem::Requirement
@@ -237,6 +253,7 @@ files:
237
253
  - app/assets/stylesheets/publinator/site.css.scss
238
254
  - app/controllers/publinator/application_controller.rb
239
255
  - app/controllers/publinator/home_controller.rb
256
+ - app/controllers/publinator/manage/pages_controller.rb
240
257
  - app/controllers/publinator/manage/publishable_controller.rb
241
258
  - app/controllers/publinator/manage/sections_controller.rb
242
259
  - app/controllers/publinator/manage/sites_controller.rb
@@ -246,6 +263,7 @@ files:
246
263
  - app/helpers/publinator/application_helper.rb
247
264
  - app/helpers/publinator/home_helper.rb
248
265
  - app/helpers/publinator/manage/sections_helper.rb
266
+ - app/models/publinator/asset_item.rb
249
267
  - app/models/publinator/domain_name.rb
250
268
  - app/models/publinator/page.rb
251
269
  - app/models/publinator/publication.rb
@@ -262,6 +280,12 @@ files:
262
280
  - app/views/publinator/home/index.html.erb
263
281
  - app/views/publinator/home/page.html.erb
264
282
  - app/views/publinator/manage/index.html.erb
283
+ - app/views/publinator/manage/pages/_form.html.erb
284
+ - app/views/publinator/manage/pages/_summary.html.erb
285
+ - app/views/publinator/manage/pages/edit.html.erb
286
+ - app/views/publinator/manage/pages/index.html.erb
287
+ - app/views/publinator/manage/pages/new.html.erb
288
+ - app/views/publinator/manage/pages/show.html.erb
265
289
  - app/views/publinator/manage/publishable/_form.html.erb
266
290
  - app/views/publinator/manage/publishable/_summary.html.erb
267
291
  - app/views/publinator/manage/publishable/edit.html.erb
@@ -279,6 +303,7 @@ files:
279
303
  - app/views/publinator/publishable/_summary.html.erb
280
304
  - app/views/publinator/publishable/index.html.erb
281
305
  - app/views/publinator/publishable/show.html.erb
306
+ - config/initializers/paperclip.rb
282
307
  - config/routes.rb
283
308
  - db/migrate/20120725194854_create_publinator_sites.rb
284
309
  - db/migrate/20120725200404_create_publinator_domain_names.rb
@@ -291,6 +316,7 @@ files:
291
316
  - db/migrate/20120726234703_create_publinator_publishable_types.rb
292
317
  - db/migrate/20121011191348_create_publinator_sections.rb
293
318
  - db/migrate/20121017134533_create_publinator_pages.rb
319
+ - db/migrate/20121020181204_create_publinator_asset_items.rb
294
320
  - lib/generators/publishable/publishable_generator.rb
295
321
  - lib/generators/publishable/templates/app/models/publishable.html.erb
296
322
  - lib/generators/publishable/templates/app/models/publishable_migration.rb.erb
@@ -317,7 +343,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
317
343
  version: '0'
318
344
  segments:
319
345
  - 0
320
- hash: -1778146319537863038
346
+ hash: 611779132086481296
321
347
  required_rubygems_version: !ruby/object:Gem::Requirement
322
348
  none: false
323
349
  requirements:
@@ -326,7 +352,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
326
352
  version: '0'
327
353
  segments:
328
354
  - 0
329
- hash: -1778146319537863038
355
+ hash: 611779132086481296
330
356
  requirements: []
331
357
  rubyforge_project:
332
358
  rubygems_version: 1.8.24