class Dropcaster::Channel
Represents a podcast feed in the RSS 2.0 format
Constants
- MAX_KEYWORD_COUNT
- STORAGE_UNITS
Public Class Methods
Instantiate a new Channel
object. sources
must be present and can be a String or Array of Strings, pointing to a one or more directories or MP3 files.
attributes
is a hash with all attributes for the channel. The following attributes are mandatory when a new channel is created:
-
:title
- Title (name) of the podcast -
:url
- URL to the podcast -
:description
- Short description of the podcast (a few words)
# File lib/dropcaster/channel.rb, line 28 def initialize(sources, attributes) # Assert mandatory attributes %i[title url description].each { |attr| raise MissingAttributeError.new(attr) if attributes[attr].blank? } @attributes = attributes @attributes[:explicit] = yes_no_or_input(attributes[:explicit]) @source_files = [] # if (sources.respond_to?(:each)) # array if sources.is_a? Array sources.each do |src| add_files(src) end else # single file or directory add_files(sources) end # If not absolute, prepend the image URL with the channel's base to make an absolute URL unless @attributes[:image_url].blank? || @attributes[:image_url] =~ /^https?:/ logger.info("Channel image URL '#{@attributes[:image_url]}' is relative, so we prepend it with the channel URL '#{@attributes[:url]}'") @attributes[:image_url] = (URI.parse(@attributes[:url]) + @attributes[:image_url]).to_s end # If enclosures_url is not given, take the channel URL as a base. if @attributes[:enclosures_url].blank? logger.info("No enclosure URL given, using the channel's enclosure URL") @attributes[:enclosures_url] = @attributes[:url] end # Warn if keyword count is larger than recommended assert_keyword_count(@attributes[:keywords]) channel_template = @attributes[:channel_template] || File.join(File.dirname(__FILE__), '..', '..', 'templates', 'channel.rss.erb') begin @erb_template = ERB.new(IO.read(channel_template)) rescue Errno::ENOENT => e raise TemplateNotFoundError.new(e.message) end end
Public Instance Methods
Fixed version of gist.github.com/260184
# File lib/dropcaster/channel.rb, line 125 def humanize_size(number) return nil if number.nil? if number.to_i < 1024 unit = number > 1 ? 'Bytes' : 'Byte' else max_exp = STORAGE_UNITS.size - 1 number = Float(number) exponent = (Math.log(number) / Math.log(1024)).to_i # Convert to base 1024 exponent = max_exp if exponent > max_exp # we need this to avoid overflow for the highest unit number /= 1024**exponent unit = STORAGE_UNITS[exponent] end '%n %u'.gsub(/%n/, number.to_i.to_s).gsub(/%u/, unit) end
from stackoverflow.com/questions/4136248
# File lib/dropcaster/channel.rb, line 115 def humanize_time(secs) [[60, :s], [60, :m], [24, :h], [1000, :d]].map { |count, name| if secs.positive? secs, n = secs.divmod(count) "#{n.to_i}#{name}" end }.compact.reverse.join(' ') end
Returns all items (episodes) of this channel, ordered by newest-first.
# File lib/dropcaster/channel.rb, line 84 def items all_items = [] @source_files.each { |src| item = Item.new(src) logger.debug("Adding new item from file #{src}") # set author and image_url from channel if empty if item.tag.artist.blank? logger.info("#{src} has no artist, using the channel's author") item.tag.artist = @attributes[:author] end if item.image_url.blank? logger.info("#{src} has no image URL set, using the channel's image URL") item.image_url = @attributes[:image_url] end # construct absolute URL, based on the channel's enclosures_url attribute item.url = URI.parse(enclosures_url) + item.file_path.each_filename.map { |p| url_encode(p) }.join('/') # Warn if keyword count is larger than recommended assert_keyword_count(item.keywords) all_items << item } all_items.sort { |x, y| y.pub_date <=> x.pub_date } end
Delegate all unknown methods to @attributes
rubocop:disable Style/MethodMissing
# File lib/dropcaster/channel.rb, line 146 def method_missing(meth, *args) m = meth.id2name if m =~ /=$/ @attributes[m.chop.to_sym] = (args.length < 2 ? args[0] : args) else @attributes[m.to_sym] end end
rubocop:enable Style/MethodMissing
# File lib/dropcaster/channel.rb, line 156 def respond_to_missing?(meth, *) (meth.id2name =~ /=$/) || super end
Returns this channel as an RSS representation. The actual rendering is done with the help of an ERB template. By default, it is expected as ../../templates/channel.rss.erb (relative) to channel.rb.
# File lib/dropcaster/channel.rb, line 77 def to_rss @erb_template.result(binding) end
Private Instance Methods
# File lib/dropcaster/channel.rb, line 162 def add_files(src) if File.directory?(src) @source_files.concat(Dir.glob(File.join(src, '*.mp3'), File::FNM_CASEFOLD)) else @source_files << src end end
# File lib/dropcaster/channel.rb, line 200 def assert_keyword_count(keywords) if keywords && MAX_KEYWORD_COUNT < keywords.size logger.info("The list of keywords has #{keywords.size} entries, which exceeds the recommended maximum of #{MAX_KEYWORD_COUNT}.") end end
snippets.dzone.com/posts/show/4578
# File lib/dropcaster/channel.rb, line 189 def truncate(string, count=30) if string.length >= count shortened = string[0, count] splitted = shortened.split(/\s/) words = splitted.length splitted[0, words - 1].join(' ') + '...' else string end end
Deal with Ruby's autoboxing of Yes, No, true, etc values in YAML
# File lib/dropcaster/channel.rb, line 173 def yes_no_or_input(flag) case flag when nil nil when true 'Yes' when false 'No' else flag end end