podcast 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README +24 -0
- data/bin/podcast +65 -0
- data/lib/mp3file.rb +28 -0
- data/lib/podcast.rb +102 -0
- data/test/test.mp3 +0 -0
- data/test/test_podcast.rb +47 -0
- metadata +44 -0
data/README
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
=begin rdoc
|
2
|
+
|
3
|
+
Podcast is a simple library and command line utility for creating
|
4
|
+
podcast files from a directory of mp3 files. Podcast will
|
5
|
+
examine mp3s, extract metadata from ID3 tags, and build an RSS
|
6
|
+
file which can then be podcast clients to download the mp3s.
|
7
|
+
|
8
|
+
You'll need to install the Ruby mp3info library installed before podcast
|
9
|
+
will work. You can grab ruby-mp3info here:
|
10
|
+
|
11
|
+
http://rubyforge.org/projects/ruby-mp3info/
|
12
|
+
|
13
|
+
Once you've got podcast installed you should be able to run the podcast
|
14
|
+
command line utility by pointing it a directory of mp3s.
|
15
|
+
|
16
|
+
% podcast --dir=/home/john/mp3s --out=podcast.xml
|
17
|
+
|
18
|
+
Please email the author with suggestions and questions.
|
19
|
+
|
20
|
+
Ed Summers <ehs@pobox.com>
|
21
|
+
|
22
|
+
Happy podcasting.
|
23
|
+
|
24
|
+
=end
|
data/bin/podcast
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
usage = <<-USAGE
|
4
|
+
|
5
|
+
usage: podcast --dir=dir [ --base=http://www.example.org/music ]
|
6
|
+
[ --title="My Mp3s" ] [ --out=rss.xml ]
|
7
|
+
|
8
|
+
dir - the directory of mp3s
|
9
|
+
title - the title of the rss feed
|
10
|
+
base - the base URL where the mp3s are available from
|
11
|
+
out - where to write the rss (STDOUT if unspecified)
|
12
|
+
|
13
|
+
example:
|
14
|
+
|
15
|
+
# write a podcast for all the files in /var/music/new that are available
|
16
|
+
# via the base url http://www.example.org/podcast to a file rss.xml
|
17
|
+
|
18
|
+
podcast --dir=/var/music/new --base=http://www.example.org/podcast
|
19
|
+
--title="My New Mp3s" --out=rss.xml
|
20
|
+
|
21
|
+
USAGE
|
22
|
+
|
23
|
+
require 'ostruct'
|
24
|
+
require 'optparse'
|
25
|
+
require 'rubygems'
|
26
|
+
require_gem 'podcast'
|
27
|
+
|
28
|
+
# defaultoptions
|
29
|
+
options = OpenStruct.new
|
30
|
+
options.dir = ''
|
31
|
+
options.help = false
|
32
|
+
options.title = 'podcast'
|
33
|
+
|
34
|
+
# read options
|
35
|
+
opts = OptionParser.new
|
36
|
+
opts.on( "-d", "--dir VAL", String ) { |val| options.dir=val }
|
37
|
+
opts.on( "-b", "--base VAL", String ) { |val| options.base=val }
|
38
|
+
opts.on( "-t", "--title VAL", String ) { |val| options.title=val }
|
39
|
+
opts.on( "-o", "--out VAL", String ) { |val| options.output=val }
|
40
|
+
opts.on( "-h", "--help" ) { |val| options.help=val }
|
41
|
+
opts.parse(ARGV)
|
42
|
+
|
43
|
+
# output usage
|
44
|
+
if options.dir == '' or options.help
|
45
|
+
puts usage
|
46
|
+
exit
|
47
|
+
end
|
48
|
+
|
49
|
+
# create podcast object
|
50
|
+
podcast = Podcast.new()
|
51
|
+
podcast.base = options.base
|
52
|
+
podcast.title = options.title
|
53
|
+
|
54
|
+
# add a directory
|
55
|
+
podcast.add_dir( options.dir )
|
56
|
+
|
57
|
+
# write off the rss
|
58
|
+
if options.output
|
59
|
+
file = File.new( options.output, 'w' )
|
60
|
+
file.write( podcast.get_rss() )
|
61
|
+
file.close
|
62
|
+
else
|
63
|
+
puts podcast.get_rss()
|
64
|
+
end
|
65
|
+
|
data/lib/mp3file.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'mp3info'
|
2
|
+
|
3
|
+
# class for representing mp3 files
|
4
|
+
class Mp3File
|
5
|
+
|
6
|
+
attr_accessor :artist, :album, :title, :file, :path, :length, :type, :mtime
|
7
|
+
|
8
|
+
def initialize(f)
|
9
|
+
file = File.new(f)
|
10
|
+
info = Mp3Info.open(f)
|
11
|
+
tag = info.tag()
|
12
|
+
@file = f
|
13
|
+
@artist = tag['artist']
|
14
|
+
@album = tag['album']
|
15
|
+
@title = tag['title']
|
16
|
+
@path = file.path()
|
17
|
+
@length = file.stat.size()
|
18
|
+
@mtime = file.stat.mtime()
|
19
|
+
@type = 'audio/mpeg'
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_s
|
23
|
+
"#{@artist} -- #{@album} -- #{@title}"
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
|
data/lib/podcast.rb
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'find'
|
2
|
+
require 'rss/0.9'
|
3
|
+
require 'Mp3File'
|
4
|
+
|
5
|
+
|
6
|
+
# Podcast is a class that makes it easy to create MP3 RSS enclosures
|
7
|
+
# from the filesystem.
|
8
|
+
#
|
9
|
+
# require 'podcast'
|
10
|
+
# p = Podcast.new
|
11
|
+
# p.title = 'test podcast'
|
12
|
+
# p.description = 'test podcast coming at ya'
|
13
|
+
# p.link = 'http://www.example.org'
|
14
|
+
# p.base = 'http://www.example.org/torrents'
|
15
|
+
# p.add_dir( '/home/john/music' )
|
16
|
+
# xml = p.get_rss()
|
17
|
+
class Podcast
|
18
|
+
|
19
|
+
attr_reader :title, :link, :description, :image, :base, :language
|
20
|
+
attr_writer :title, :link, :description, :image, :base, :language
|
21
|
+
|
22
|
+
include Enumerable
|
23
|
+
|
24
|
+
def initialize
|
25
|
+
@mp3s = []
|
26
|
+
@language = "English"
|
27
|
+
@base = ''
|
28
|
+
end
|
29
|
+
|
30
|
+
# add an mp3 file to the podcast
|
31
|
+
def add_mp3( file )
|
32
|
+
mp3 = Mp3File.new( file )
|
33
|
+
@mp3s.push( mp3 )
|
34
|
+
end
|
35
|
+
|
36
|
+
# add a directory location to the podcast
|
37
|
+
# the directory will be recursively search
|
38
|
+
# for mp3 files.
|
39
|
+
def add_dir( dir )
|
40
|
+
# we chdir into the directory so that file paths will be relative
|
41
|
+
pwd = Dir.pwd
|
42
|
+
Dir.chdir( dir )
|
43
|
+
Find.find( '.' ) do |f|
|
44
|
+
if ( f =~ /\.mp3$/ )
|
45
|
+
f.sub!( %r{^./}, '' ) # remove leading './'
|
46
|
+
add_mp3(f)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
# go back to original directory
|
50
|
+
Dir.chdir( pwd )
|
51
|
+
end
|
52
|
+
|
53
|
+
# the total amount of files in the podcast
|
54
|
+
def size
|
55
|
+
@mp3s.size
|
56
|
+
end
|
57
|
+
|
58
|
+
# write the podcast file
|
59
|
+
def get_rss()
|
60
|
+
rss = RSS::Rss.new( "0.9" )
|
61
|
+
channel = RSS::Rss::Channel.new
|
62
|
+
channel.title = @title
|
63
|
+
channel.description = @description
|
64
|
+
channel.link = @link
|
65
|
+
channel.language = @language
|
66
|
+
rss.channel = channel
|
67
|
+
|
68
|
+
if ( @image )
|
69
|
+
image = RSS::Rss::Channel::Image.new
|
70
|
+
image.url = @image
|
71
|
+
image.title = @title
|
72
|
+
image.link = @link
|
73
|
+
channel.image = image
|
74
|
+
end
|
75
|
+
|
76
|
+
for mp3 in @mp3s
|
77
|
+
next if ! mp3.artist
|
78
|
+
item = RSS::Rss::Channel::Item.new
|
79
|
+
item.title = mp3
|
80
|
+
## add a base url
|
81
|
+
if base != ''
|
82
|
+
link = base + '/' + mp3.path
|
83
|
+
else
|
84
|
+
link = mp3.path
|
85
|
+
end
|
86
|
+
item.link = link
|
87
|
+
item.enclosure = RSS::Rss::Channel::Item::Enclosure.new(
|
88
|
+
link, mp3.length, mp3.type )
|
89
|
+
channel.items << item
|
90
|
+
end
|
91
|
+
|
92
|
+
return rss.to_s
|
93
|
+
end
|
94
|
+
|
95
|
+
def each
|
96
|
+
@songs.each do |s|
|
97
|
+
yield s
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
data/test/test.mp3
ADDED
Binary file
|
@@ -0,0 +1,47 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$:.push( '../lib' )
|
4
|
+
require 'test/unit'
|
5
|
+
require 'podcast'
|
6
|
+
|
7
|
+
class PodcastTest < Test::Unit::TestCase
|
8
|
+
|
9
|
+
def test_constructor
|
10
|
+
p = Podcast.new
|
11
|
+
assert( p.class == Podcast )
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_add_mp3
|
15
|
+
p = Podcast.new
|
16
|
+
p.add_mp3( 'test.mp3' )
|
17
|
+
p.add_mp3( 'test.mp3' )
|
18
|
+
p.add_mp3( 'test.mp3' )
|
19
|
+
assert_equal( p.size(), 3 )
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_add_dir
|
23
|
+
p = Podcast.new
|
24
|
+
p.add_dir( '.' )
|
25
|
+
assert_equal( p.size(), 1 )
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_get_rss
|
29
|
+
p = Podcast.new
|
30
|
+
p.title = 'test podcast'
|
31
|
+
p.description = 'test podcast coming at ya'
|
32
|
+
p.link = 'http://www.example.org'
|
33
|
+
p.image = 'http://www.example.org/icon.png'
|
34
|
+
p.base = 'http://www.example.org/torrents'
|
35
|
+
## add using directory so we can confirm it is stripped
|
36
|
+
p.add_dir( '../test' )
|
37
|
+
xml = p.get_rss()
|
38
|
+
|
39
|
+
# parse the rss
|
40
|
+
parser = RSS::Parser.new( '0.9' )
|
41
|
+
rss = RSS::Parser.parse( xml )
|
42
|
+
items = rss.items()
|
43
|
+
assert( items.size == 1 )
|
44
|
+
assert_equal( items[0].link, 'http://www.example.org/torrents/test.mp3')
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
metadata
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.8.1
|
3
|
+
specification_version: 1
|
4
|
+
name: podcast
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.0.2
|
7
|
+
date: 2004-11-28
|
8
|
+
summary: Create podcasts from MP3 files
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
author: Ed Summers
|
12
|
+
email: ehs@pobox.com
|
13
|
+
homepage: http://www.inkdroid.org
|
14
|
+
rubyforge_project:
|
15
|
+
description:
|
16
|
+
autorequire: podcast
|
17
|
+
default_executable:
|
18
|
+
bindir: bin
|
19
|
+
has_rdoc: true
|
20
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
21
|
+
requirements:
|
22
|
+
-
|
23
|
+
- ">"
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: 0.0.0
|
26
|
+
version:
|
27
|
+
platform: ruby
|
28
|
+
files:
|
29
|
+
- bin/podcast
|
30
|
+
- lib/mp3file.rb
|
31
|
+
- lib/podcast.rb
|
32
|
+
- test/test.mp3
|
33
|
+
- test/test_podcast.rb
|
34
|
+
- README
|
35
|
+
test_files:
|
36
|
+
- test/test_podcast.rb
|
37
|
+
rdoc_options: []
|
38
|
+
extra_rdoc_files:
|
39
|
+
- README
|
40
|
+
executables:
|
41
|
+
- podcast
|
42
|
+
extensions: []
|
43
|
+
requirements: []
|
44
|
+
dependencies: []
|