refinerycms-podcast 0.5 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/app/controllers/refinery/podcasts/admin/podcasts_controller.rb +24 -0
  3. data/app/controllers/refinery/podcasts/podcasts_controller.rb +39 -0
  4. data/app/models/refinery/podcasts/podcast.rb +41 -0
  5. data/app/views/refinery/podcasts/admin/podcasts/_actions.html.erb +23 -0
  6. data/app/views/refinery/podcasts/admin/podcasts/_form.html.erb +98 -0
  7. data/app/views/refinery/podcasts/admin/podcasts/_podcast.html.erb +22 -0
  8. data/app/views/refinery/podcasts/admin/podcasts/_podcasts.html.erb +2 -0
  9. data/app/views/refinery/podcasts/admin/podcasts/_records.html.erb +18 -0
  10. data/app/views/refinery/podcasts/admin/podcasts/_sortable_list.html.erb +5 -0
  11. data/app/views/refinery/podcasts/admin/podcasts/edit.html.erb +1 -0
  12. data/app/views/refinery/podcasts/admin/podcasts/index.html.erb +7 -0
  13. data/app/views/refinery/podcasts/admin/podcasts/new.html.erb +1 -0
  14. data/app/views/refinery/podcasts/podcasts/index.html.erb +11 -0
  15. data/app/views/refinery/podcasts/podcasts/index.rss.builder +71 -0
  16. data/app/views/refinery/podcasts/podcasts/show.html.erb +59 -0
  17. data/config/locales/cs.yml +34 -0
  18. data/config/locales/en.yml +32 -14
  19. data/config/locales/es.yml +35 -0
  20. data/config/locales/fr.yml +34 -0
  21. data/config/locales/nb.yml +34 -0
  22. data/config/locales/nl.yml +32 -14
  23. data/config/routes.rb +15 -6
  24. data/db/migrate/1_create_refinery_podcasts.rb +33 -0
  25. data/db/migrate/2_add_slug_to_refinery_podcasts.rb +8 -0
  26. data/db/migrate/3_add_image_id_to_refinery_podcasts.rb +8 -0
  27. data/db/seeds.rb +25 -0
  28. data/lib/generators/refinery/podcasts/podcasts_generator.rb +24 -0
  29. data/lib/generators/refinery/podcasts/templates/config/initializers/refinery/podcasts.rb.erb +47 -0
  30. data/lib/refinery/podcasts.rb +22 -0
  31. data/lib/refinery/podcasts/configuration.rb +20 -0
  32. data/lib/refinery/podcasts/engine.rb +22 -0
  33. data/lib/refinerycms-podcast.rb +1 -0
  34. data/lib/tasks/refinery/podcasts.rake +13 -0
  35. data/readme.md +10 -44
  36. metadata +125 -62
  37. data/app/controllers/admin/podcasts_controller.rb +0 -5
  38. data/app/controllers/podcasts_controller.rb +0 -12
  39. data/app/models/podcast.rb +0 -24
  40. data/app/views/admin/podcasts/_form.html.erb +0 -59
  41. data/app/views/admin/podcasts/_podcast.html.erb +0 -16
  42. data/app/views/admin/podcasts/edit.html.erb +0 -1
  43. data/app/views/admin/podcasts/index.html.erb +0 -34
  44. data/app/views/admin/podcasts/new.html.erb +0 -1
  45. data/app/views/podcasts/index.rss.builder +0 -56
  46. data/generators/podcast/podcast_generator.rb +0 -23
  47. data/generators/podcast/templates/migration.rb +0 -32
  48. data/lib/gemspec.rb +0 -30
  49. data/lib/refinery/podcast.rb +0 -15
  50. data/lib/tasks/podcast.rake +0 -35
  51. data/license.md +0 -21
  52. data/rails/init.rb +0 -14
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4774257307552821fe14e0c6e1932c4ec1cdedd4
4
+ data.tar.gz: 15ea1c7a5502498c0139b6af0546d052a5e87696
5
+ SHA512:
6
+ metadata.gz: 14f58bcf61a371122544f1d9430aef8666feed39a6dc71cb2cb70ff07a36d57f66cf5f32b7369658fab226d90a09432026cba764cf1a614f22581ca61193301a
7
+ data.tar.gz: 5c81491cbbc2db8a672ed4cc72d3ff1ae3bb2c1203a0c202ae0cf87e41232e40671fef0803d5946bf02f6e205af1062253babdb44b31a659b496dd2c224d4f71
@@ -0,0 +1,24 @@
1
+ module Refinery
2
+ module Podcasts
3
+ module Admin
4
+ class PodcastsController < ::Refinery::AdminController
5
+
6
+ crudify :'refinery/podcasts/podcast', order: 'published_at DESC'
7
+
8
+ private
9
+
10
+ def podcast_params
11
+ params.require(:podcast).permit(permitted_podcast_params)
12
+ end
13
+
14
+ def permitted_podcast_params
15
+ [
16
+ :title, :author, :subtitle, :file_id, :image_id,
17
+ :published_at, :duration, :keywords, :summary, :position
18
+ ]
19
+ end
20
+
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,39 @@
1
+ module Refinery
2
+ module Podcasts
3
+ class PodcastsController < ::ApplicationController
4
+
5
+ before_filter :find_all_podcasts
6
+ before_filter :find_page
7
+
8
+ def index
9
+ respond_to do |format|
10
+ format.rss do
11
+ render :layout => false
12
+ end
13
+ format.html {
14
+ present @page
15
+ }
16
+ end
17
+ end
18
+
19
+ def show
20
+ @podcast = Podcast.find params[:id]
21
+
22
+ # you can use meta fields from your model instead (e.g. browser_title)
23
+ # by swapping @page for @podcast in the line below:
24
+ present @page
25
+ end
26
+
27
+ protected
28
+
29
+ def find_all_podcasts
30
+ @podcasts = Podcast.order 'published_at DESC'
31
+ end
32
+
33
+ def find_page
34
+ @page = ::Refinery::Page.where(:link_url => "/podcasts").first
35
+ end
36
+
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,41 @@
1
+ require 'acts_as_indexed'
2
+ require 'friendly_id'
3
+
4
+ module Refinery
5
+ module Podcasts
6
+ class Podcast < Refinery::Core::BaseModel
7
+ self.table_name = 'refinery_podcasts'
8
+
9
+ acts_as_indexed :fields => [:title, :author, :subtitle, :duration, :keywords, :summary]
10
+
11
+ validates :title, :presence => true, :uniqueness => true
12
+
13
+ belongs_to :file, :class_name => '::Refinery::Resource'
14
+ belongs_to :image, :class_name => '::Refinery::Image'
15
+
16
+ extend FriendlyId
17
+
18
+ friendly_id :title, :use => :slugged
19
+
20
+ def episode_number
21
+ self.class.order('published_at DESC').
22
+ where(self.class.arel_table[:id].lteq(self.id)).
23
+ count
24
+ end
25
+
26
+ class << self
27
+ def default_scope
28
+ order "published_at DESC"
29
+ end
30
+
31
+ def published
32
+ where arel_table[:published_at].lteq(Date.today)
33
+ end
34
+
35
+ def latest(limit = 10)
36
+ published.limit limit
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,23 @@
1
+ <ul>
2
+ <% if ::Refinery::Podcasts::Admin::PodcastsController.searchable? %>
3
+ <li><%= render '/refinery/admin/search', url: refinery.admin_pages_path -%></li>
4
+ <% end %>
5
+ <li>
6
+ <%= link_to t('.create_new'), refinery.new_podcasts_admin_podcast_path,
7
+ :class => "add_icon" %>
8
+ </li>
9
+ <% if !searching? && ::Refinery::Podcasts::Admin::PodcastsController.sortable? && ::Refinery::Podcasts::Podcast.any? %>
10
+ <li>
11
+ <%= link_to t('.reorder', :what => "Podcasts"),
12
+ refinery.podcasts_admin_podcasts_path,
13
+ :id => "reorder_action",
14
+ :class => "reorder_icon" %>
15
+
16
+ <%= link_to t('.reorder_done', :what => "Podcasts"),
17
+ refinery.podcasts_admin_podcasts_path,
18
+ :id => "reorder_action_done",
19
+ :style => "display: none;",
20
+ :class => "reorder_icon" %>
21
+ </li>
22
+ <% end %>
23
+ </ul>
@@ -0,0 +1,98 @@
1
+ <%= form_for [refinery, :podcasts_admin, @podcast] do |f| -%>
2
+ <%= render '/refinery/admin/error_messages',
3
+ :object => @podcast,
4
+ :include_object_name => true %>
5
+
6
+ <div class='field'>
7
+ <%= f.label :title -%>
8
+ <%= f.text_field :title, :class => 'larger widest' -%>
9
+ </div>
10
+
11
+ <div class='field'>
12
+ <%= f.label :subtitle -%>
13
+ <%= f.text_field :subtitle, :size => 100 -%>
14
+ </div>
15
+
16
+ <div class='field'>
17
+ <%= f.label :author -%>
18
+ <%= f.text_field :author -%>
19
+ </div>
20
+
21
+ <div class='field'>
22
+ <span class='label_with_help'>
23
+ <%= f.label :file_id, 'Podcast episode file' -%>
24
+ <%= refinery_help_tag "Supported file formats include .m4a, .mp3, .mov, .mp4, .m4v, and .pdf" %>
25
+ </span>
26
+ <%= render '/refinery/admin/resource_picker',
27
+ :f => f,
28
+ :field => :file_id,
29
+ :resource => @podcast.file,
30
+ :description => 'podcast' %>
31
+ </div>
32
+
33
+ <div class="field">
34
+ <span class="label_with_help">
35
+ <%= f.label :image_id, "Podcast episode image" -%>
36
+ <%= refinery_help_tag "iTunes prefers square .jpg or .png images that are between 1400 x 1400 pixels and 3000 x 3000 pixels" %>
37
+ </span>
38
+ <%= render :partial => "/refinery/admin/image_picker", :locals => {
39
+ :f => f,
40
+ :field => :image_id,
41
+ :image => @podcast.image,
42
+ :toggle_image_display => false
43
+ } %>
44
+ </div>
45
+
46
+ <div class='field'>
47
+ <%= f.label :published_at -%>
48
+ <%= f.date_select :published_at -%>
49
+ </div>
50
+
51
+ <div class='field'>
52
+ <span class='label_with_help'>
53
+ <%= f.label :duration -%>
54
+ <%= refinery_help_tag "In HH:MM:SS format. E.g. \"10:22\" for 10 minutes 22 seconds" %>
55
+ </span>
56
+ <%= f.text_field :duration, :size => 6 -%>
57
+ </div>
58
+
59
+ <div class='field'>
60
+ <span class='label_with_help'>
61
+ <%= f.label :keywords -%>
62
+ <%= refinery_help_tag "Up to 12 keywords separated by commas. <br/><br/>E.g. rails, ruby on rails, refinerycms, refinery. <br/><br/>According to iTunes, the best use for keywords is to include common misspellings of your name or title, to ensure your podcast is still searchable despite a misspelling. To prevent keyword abuse, iTunes indexes only the first 12 keywords found in this tag." %>
63
+ </span>
64
+ <%= f.text_field :keywords, :size => 100 -%><br/>
65
+ </div>
66
+
67
+ <div class='field'>
68
+ <div id='page-tabs' class='clearfix ui-tabs ui-widget ui-widget-content ui-corner-all'>
69
+ <ul id='page_parts'>
70
+ <% [:summary].each_with_index do |part, part_index| %>
71
+ <li class='ui-state-default<%= ' ui-state-active' if part_index == 0 %>'>
72
+ <%= link_to t("#{part}", :scope => "activerecord.attributes.refinery/podcasts/podcast", :default => part.to_s.titleize), "##{part}" %>
73
+ </li>
74
+ <% end %>
75
+ </ul>
76
+ <div id='page_part_editors'>
77
+ <% [:summary].each do |part| %>
78
+ <div class='page_part' id='<%= part %>'>
79
+ <%= f.text_area part, :rows => 20, :class => 'wymeditor widest' -%>
80
+ </div>
81
+ <% end %>
82
+ </div>
83
+ </div>
84
+
85
+ </div>
86
+
87
+ <%= render '/refinery/admin/form_actions', :f => f,
88
+ :continue_editing => false,
89
+ :delete_title => t('delete', :scope => 'refinery.podcasts.admin.podcasts.podcast'),
90
+ :delete_confirmation => t('message', :scope => 'refinery.admin.delete', :title => @podcast.title) %>
91
+ <% end -%>
92
+ <% content_for :javascripts do %>
93
+ <script>
94
+ $(document).ready(function(){
95
+ page_options.init(false, '', '');
96
+ });
97
+ </script>
98
+ <% end %>
@@ -0,0 +1,22 @@
1
+ <li class='clearfix record <%= cycle("on", "on-hover") %>' id="<%= dom_id(podcast) -%>">
2
+ <span class='title'>
3
+ #<%= podcast.episode_number %> <%= podcast.title %>
4
+ <span class="preview">- <%= truncate(podcast.subtitle, :length => 50) %></span>
5
+ </span>
6
+ <span class='actions'>
7
+
8
+ <%= link_to refinery_icon_tag("application_go.png"), refinery.podcasts_podcast_path(podcast),
9
+ :title => t('.view_live_html'),
10
+ :target => "_blank" %>
11
+
12
+ <%= link_to refinery_icon_tag("application_edit.png"), refinery.edit_podcasts_admin_podcast_path(podcast),
13
+ :title => t('.edit') %>
14
+ <%= link_to refinery_icon_tag("delete.png"), refinery.podcasts_admin_podcast_path(podcast),
15
+ :class => "cancel confirm-delete",
16
+ :title => t('.delete'),
17
+ :data => {
18
+ :confirm => t('message', :scope => 'refinery.admin.delete', :title => podcast.title)
19
+ },
20
+ :method => :delete %>
21
+ </span>
22
+ </li>
@@ -0,0 +1,2 @@
1
+ <%= will_paginate @podcasts if Refinery::Podcasts::Admin::PodcastsController.pageable? %>
2
+ <%= render 'sortable_list' %>
@@ -0,0 +1,18 @@
1
+ <% if searching? %>
2
+ <h2><%= t('results_for', :scope => 'refinery.admin.search', :query => params[:search]) %></h2>
3
+ <% end %>
4
+ <div class='pagination_container'>
5
+ <% if @podcasts.any? %>
6
+ <%= render 'podcasts' %>
7
+ <% else %>
8
+ <p>
9
+ <% unless searching? %>
10
+ <strong>
11
+ <%= t('.no_items_yet') %>
12
+ </strong>
13
+ <% else %>
14
+ <%= t('no_results', :scope => 'refinery.admin.search') %>
15
+ <% end %>
16
+ </p>
17
+ <% end %>
18
+ </div>
@@ -0,0 +1,5 @@
1
+ <ul id='sortable_list'>
2
+ <%= render :partial => 'podcast', :collection => @podcasts %>
3
+ </ul>
4
+ <%= render '/refinery/admin/sortable_list',
5
+ :continue_reordering => (local_assigns.keys.include?(:continue_reordering)) ? continue_reordering : true %>
@@ -0,0 +1 @@
1
+ <%= render 'form' %>
@@ -0,0 +1,7 @@
1
+ <section id='records'>
2
+ <%= render 'records' %>
3
+ </section>
4
+ <aside id='actions'>
5
+ <%= render 'actions' %>
6
+ </aside>
7
+ <%= render '/refinery/admin/make_sortable', :tree => false if !searching? and ::Refinery::Podcasts::Admin::PodcastsController.sortable? and ::Refinery::Podcasts::Podcast.count > 1 %>
@@ -0,0 +1 @@
1
+ <%= render 'form' %>
@@ -0,0 +1,11 @@
1
+ <% content_for :body do %>
2
+ <ul id="podcasts">
3
+ <% @podcasts.each do |podcast| %>
4
+ <li>
5
+ <%= link_to podcast.title, refinery.podcasts_podcast_path(podcast) %>
6
+ </li>
7
+ <% end %>
8
+ </ul>
9
+ <% end %>
10
+
11
+ <%= render '/refinery/content_page' %>
@@ -0,0 +1,71 @@
1
+ require 'uri' # used for URI.encode
2
+ xml.instruct!
3
+
4
+ xml.rss 'xmlns:itunes' => 'http://www.itunes.com/dtds/podcast-1.0.dtd', :version => '2.0', 'xmlns:atom' => 'http://www.w3.org/2005/Atom' do
5
+ xml.channel do
6
+ # Points to your website (e.g. http://yoursite.com/)
7
+ base_url = request.protocol + request.host_with_port
8
+
9
+ # NOTE: Fill in everything with your own data down to the categories.
10
+ xml.title Refinery::Podcasts.title
11
+
12
+ # Points to your website (e.g. http://yoursite.com/)
13
+ xml.link base_url
14
+
15
+ # Points to your podcast feed (e.g. http://yoursite.com/podcasts.rss)
16
+ xml.tag!('atom:link', :href => refinery.podcasts_podcasts_url(format: :rss), :rel => 'self', :type => 'application/rss+xml')
17
+
18
+ # Accepted values are those in the ISO 639-1 Alpha-2 list (two-letter language codes, some with possible modifiers, such as 'en-us').
19
+ xml.language Refinery::Podcasts.language
20
+
21
+ xml.copyright "© #{Time.now.year} #{Refinery::Core.site_name}"
22
+ xml.tag!('itunes:subtitle', Refinery::Podcasts.subtitle)
23
+
24
+ # The content of this tag is shown in the Artist column in iTunes.
25
+ xml.tag!('itunes:author', Refinery::Podcasts.author)
26
+
27
+ # This tag should be used to indicate whether or not your podcast contains
28
+ # explicit material. The three values for this tag are "yes", "no", and "clean".
29
+ xml.tag!('itunes:explicit', Refinery::Podcasts.explicit_content)
30
+
31
+ # The contents of this tag are shown in a separate window that appears when the
32
+ # "circled i" in the Description column is clicked. It also appears on the iTunes
33
+ # page for your podcast. This field can be up to 4000 characters.
34
+ xml.tag!('itunes:summary', Refinery::Podcasts.description)
35
+ xml.description Refinery::Podcasts.description
36
+
37
+ # This tag contains information that will be used to contact the owner of the podcast
38
+ # for communication specifically about their podcast. It will not be publicly displayed.
39
+ xml.tag!('itunes:owner') do |owner|
40
+ xml.tag!('itunes:name', Refinery::Podcasts.owner_name)
41
+ xml.tag!('itunes:email', Refinery::Podcasts.owner_email)
42
+ end
43
+
44
+ # upload an image to your resources tab and link it in here
45
+ # iTunes prefers square .jpg or .png images that are between
46
+ # 1400 x 1400 pixels and 3000 x 3000 pixels
47
+ xml.tag!('itunes:image', :href => Refinery::Podcasts.image_url)
48
+
49
+ # select from the list of categories here:
50
+ # https://help.apple.com/itc/podcasts_connect/?lang=en#/itc9267a2f12
51
+ xml.tag!('itunes:category', :text => Refinery::Podcasts.category) do |node|
52
+ xml.tag!('itunes:category', :text => Refinery::Podcasts.subcategory)
53
+ end
54
+
55
+ @podcasts.each do |item|
56
+ item_url = request.protocol + request.host_with_port + item.file.url
57
+ xml.item do
58
+ xml.title item.title
59
+ xml.tag!('itunes:author', item.author)
60
+ xml.tag!('itunes:subtitle', item.subtitle)
61
+ xml.tag!('itunes:summary', strip_tags(item.summary))
62
+ xml.enclosure :url => item_url, :length => item.file.size, :type => item.file.file_mime_type
63
+ xml.guid item_url
64
+ xml.tag!('pubDate', item.published_at.to_time.rfc2822)
65
+ xml.tag!('itunes:duration', item.duration)
66
+ xml.tag!('itunes:keywords', item.keywords)
67
+ xml.tag!('itunes:explicit', Refinery::Podcasts.explicit_content)
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,59 @@
1
+ <% content_for :body_content_title do %>
2
+ <%= @podcast.title %>: <%= @podcast.subtitle %>
3
+ <% end %>
4
+
5
+ <% content_for :body do %>
6
+ <section>
7
+ <h1>Author</h1>
8
+ <p>
9
+ <%=raw @podcast.author %>
10
+ </p>
11
+ </section>
12
+ <% if @podcast.file.present? %>
13
+ <section>
14
+ <h1>Listen Now</h1>
15
+ <p>
16
+ <%= link_to 'listen now', @podcast.file.url %>
17
+ </p>
18
+ </section>
19
+ <% end %>
20
+ <section>
21
+ <h1>Published At</h1>
22
+ <p>
23
+ <%=raw @podcast.published_at %>
24
+ </p>
25
+ </section>
26
+ <section>
27
+ <h1>Duration</h1>
28
+ <p>
29
+ <%=raw @podcast.duration %>
30
+ </p>
31
+ </section>
32
+ <section>
33
+ <h1>Keywords</h1>
34
+ <p>
35
+ <%=raw @podcast.keywords %>
36
+ </p>
37
+ </section>
38
+ <section>
39
+ <h1>Summary</h1>
40
+ <p>
41
+ <%=raw @podcast.summary %>
42
+ </p>
43
+ </section>
44
+ <% end %>
45
+
46
+ <% content_for :side_body do %>
47
+ <aside>
48
+ <h2><%= t('.other') %></h2>
49
+ <ul id="podcasts">
50
+ <% @podcasts.each do |podcast| %>
51
+ <li>
52
+ <%= link_to podcast.title, refinery.podcasts_podcast_path(podcast) %>
53
+ </li>
54
+ <% end %>
55
+ </ul>
56
+ </aside>
57
+ <% end %>
58
+
59
+ <%= render '/refinery/content_page' %>