refinerycms-podcast 0.5 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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' %>