diff --git a/Gemfile b/Gemfile index 7280eeebc..e3baba302 100644 --- a/Gemfile +++ b/Gemfile @@ -37,6 +37,9 @@ gem 'rack-attack' gem 'google_drive' gem 'lazy_high_charts' +# For RSS feed +gem 'ruby-mp3info', :require => 'mp3info' + group :development do gem 'web-console' gem 'spring' diff --git a/Gemfile.lock b/Gemfile.lock index 07732c6a9..d5ca375b3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -285,6 +285,7 @@ GEM rspec-retry (0.6.1) rspec-core (> 3.3) rspec-support (3.8.0) + ruby-mp3info (0.8.10) ruby_dep (1.5.0) ruby_parser (3.12.0) sexp_processor (~> 4.9) @@ -428,6 +429,7 @@ DEPENDENCIES rake rspec-rails (~> 3.5) rspec-retry + ruby-mp3info sass-rails scrivito (~> 1.15.0) scrivito_section_widgets diff --git a/app/controllers/podcasts_controller.rb b/app/controllers/podcasts_controller.rb index 586e0462c..f5aa1673d 100644 --- a/app/controllers/podcasts_controller.rb +++ b/app/controllers/podcasts_controller.rb @@ -14,4 +14,15 @@ def show @content = Kramdown::Document.new(@episode.content, input: 'GFM').to_html @url = request.url end + + def feed + @episodes = Podcast.all.sort_by{|episode| episode.published_at} + @base_url = request.base_url + @author = "一般社団法人 CoderDojo Japan" + @art_work_url = "https://coderdojo.jp/podcasts/cover.jpg" + @current_year = Time.current.year + respond_to do |format| + format.rss { render :layout => false } + end + end end diff --git a/app/models/podcast.rb b/app/models/podcast.rb index 642191e97..bd0df6d13 100644 --- a/app/models/podcast.rb +++ b/app/models/podcast.rb @@ -28,6 +28,20 @@ def exists?(offset: 0) File.exists?("#{DIR_PATH}/#{self.filename.to_i + offset}.md") end + def filesize + @size ||= File.size("#{DIR_PATH}/#{self.filename}.mp3") + end + + def duration + return @duration if @duration + + path = "#{DIR_PATH}/#{self.filename}.mp3" + open_opts = { :encoding => 'utf-8' } + Mp3Info.open(path, open_opts) do |mp3info| + @duration = Time.at(mp3info.length).utc.strftime('%H:%M:%S') + end + end + def title @title ||= exists? ? self.content.lines.first[2..-1].strip.gsub('
', '') : '' end @@ -36,6 +50,10 @@ def description @desc ||= exists? ? self.content.lines.reject{|l| l =~ /^(\n|<)/ }.second.delete('
').strip : '' end + def published_at + @published_at ||= exists? ? Time.parse(self.content.lines.second.gsub(/<.+?>/, '').delete('収録日: ')) : '' + end + def content @content ||= exists? ? File.read(path) : '' end diff --git a/app/views/podcasts/feed.rss.builder b/app/views/podcasts/feed.rss.builder new file mode 100644 index 000000000..72650ed74 --- /dev/null +++ b/app/views/podcasts/feed.rss.builder @@ -0,0 +1,36 @@ +xml.instruct! :xml, :version => "1.0" +xml.rss :version => "2.0", "xmlns:itunes" => "http://www.itunes.com/dtds/Podcast-1.0.dtd" do + xml.channel do + xml.title full_title "" + xml.description full_description "" + xml.link root_url + xml.image @art_work_url + xml.author @author + xml.copyright "Copyright © 2012-#{@current_year} #{@author}" + xml.language "ja" + xml.itunes :category, :text => "Technology" do + xml.itunes :category, :text => "Software How-To" + xml.itunes :category, :text => "Podcasting" + end + xml.itunes :type, "serial" + xml.itunes :explicit, "clean" + + @episodes.each do |episode| + xml.item do + xml.title episode.title + xml.author @author + xml.description episode.description + xml.link "#{@base_url}#{episode.url}" + xml.guid({:isPermaLink => "false"}, "#{@base_url}#{episode.url}") + xml.itunes :explicit, "clean" + xml.published_at episode.published_at.rfc2822 + xml.enclosure({ + :url => "#{@base_url}#{episode.url}.mp3", + :length => episode.filesize, + :type => "audio/mpeg"} + ) + xml.itunes :duration, episode.duration + end + end + end +end diff --git a/config/routes.rb b/config/routes.rb index b373d85b2..6b6c843ce 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -11,6 +11,7 @@ get "/docs/charter_en", to: redirect('/charter_en') get "/docs/financial-report", to: redirect('/financial-report') get "/login", to: redirect('/login-8717e64efaf19d7d') + get "/podcasts/feed" => "podcasts#feed" get "/charter" => "docs#show", id: 'charter' get "/charter_en" => "docs#show", id: 'charter_en' get "/financial-report" => "docs#show", id: 'financial-report' diff --git a/public/podcasts/apple-rss-cover.jpg b/public/podcasts/apple-rss-cover.jpg new file mode 100644 index 000000000..5b41b4d9a Binary files /dev/null and b/public/podcasts/apple-rss-cover.jpg differ diff --git a/public/podcasts/apple-rss-cover.pxm b/public/podcasts/apple-rss-cover.pxm new file mode 100644 index 000000000..cd138ef7b Binary files /dev/null and b/public/podcasts/apple-rss-cover.pxm differ