Class: Dropcaster::Channel
- Inherits:
-
Object
- Object
- Dropcaster::Channel
- Includes:
- ERB::Util
- Defined in:
- lib/dropcaster/channel.rb
Overview
Represents a podcast feed in the RSS 2.0 format
Constant Summary collapse
- STORAGE_UNITS =
%w(Byte KB MB GB TB)
- MAX_KEYWORD_COUNT =
12
Instance Method Summary collapse
-
#humanize_size(number) ⇒ Object
Fixed version of gist.github.com/260184.
- #humanize_time(secs) ⇒ Object
-
#initialize(sources, attributes) ⇒ Channel
constructor
Instantiate a new Channel object.
-
#items ⇒ Object
Returns all items (episodes) of this channel, ordered by newest-first.
-
#method_missing(meth, *args) ⇒ Object
delegate all unknown methods to @attributes.
-
#to_rss ⇒ Object
Returns this channel as an RSS representation.
Constructor Details
#initialize(sources, attributes) ⇒ Channel
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)
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/dropcaster/channel.rb', line 24 def initialize(sources, attributes) # Assert mandatory attributes [: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 = Array.new # 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?:/ Dropcaster.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? Dropcaster.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), 0, "%<>") rescue Errno::ENOENT => e raise TemplateNotFoundError.new(e.) end end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(meth, *args) ⇒ Object
delegate all unknown methods to @attributes
143 144 145 146 147 148 149 150 |
# File 'lib/dropcaster/channel.rb', line 143 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 |
Instance Method Details
#humanize_size(number) ⇒ Object
Fixed version of gist.github.com/260184
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/dropcaster/channel.rb', line 122 def humanize_size(number) return nil if number.nil? storage_units_format = '%n %u' if number.to_i < 1024 unit = number > 1 ? 'Bytes' : 'Byte' return storage_units_format.gsub(/%n/, number.to_i.to_s).gsub(/%u/, unit) 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] return storage_units_format.gsub(/%n/, number.to_i.to_s).gsub(/%u/, unit) end end |
#humanize_time(secs) ⇒ Object
112 113 114 115 116 117 118 119 |
# File 'lib/dropcaster/channel.rb', line 112 def humanize_time(secs) [[60, :s], [60, :m], [24, :h], [1000, :d]].map{ |count, name| if secs > 0 secs, n = secs.divmod(count) "#{n.to_i}#{name}" end }.compact.reverse.join(' ') end |
#items ⇒ Object
Returns all items (episodes) of this channel, ordered by newest-first.
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/dropcaster/channel.rb', line 80 def items all_items = Array.new @source_files.each{|src| item = Item.new(src) Dropcaster.logger.debug("Adding new item from file #{src}") # set author and image_url from channel if empty if item.artist.blank? Dropcaster.logger.info("#{src} has no artist, using the channel's author") item.tag.artist = @attributes[:author] end if item.image_url.blank? Dropcaster.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) + URI.encode(item.file_name)) # 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 |
#to_rss ⇒ Object
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.
73 74 75 |
# File 'lib/dropcaster/channel.rb', line 73 def to_rss @erb_template.result(binding) end |