podcast 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/README +8 -6
- data/bin/podcast +29 -44
- data/lib/podcast.rb +92 -78
- data/test/{test_podcast.rb → ts_podcast.rb} +17 -17
- metadata +9 -7
- data/lib/mp3file.rb +0 -28
data/README
CHANGED
@@ -6,19 +6,21 @@ examine mp3s, extract metadata from ID3 tags, and build an RSS
|
|
6
6
|
file which can then be podcast clients to download the mp3s.
|
7
7
|
|
8
8
|
You'll need to install the Ruby mp3info library installed before podcast
|
9
|
-
will work
|
9
|
+
will work:
|
10
|
+
|
11
|
+
gem install ruby-mp3info
|
12
|
+
|
13
|
+
Or you can grab ruby-mp3info here:
|
10
14
|
|
11
15
|
http://rubyforge.org/projects/ruby-mp3info/
|
12
16
|
|
13
|
-
Once you've
|
14
|
-
command line utility
|
17
|
+
Once you've installed ruby-mp3info and podcast you should have a
|
18
|
+
command line utility you can run on a directory of mp3 files:
|
15
19
|
|
16
|
-
% podcast --dir=/home/
|
20
|
+
% podcast --dir=/home/ed/mp3s --out=podcast.rss
|
17
21
|
|
18
22
|
Please email the author with suggestions and questions.
|
19
23
|
|
20
24
|
Ed Summers <ehs@pobox.com>
|
21
25
|
|
22
|
-
Happy podcasting.
|
23
|
-
|
24
26
|
=end
|
data/bin/podcast
CHANGED
@@ -1,65 +1,50 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
|
3
|
+
# == Synopsis
|
4
|
+
#
|
5
|
+
# Generate a podcast file from a directory of mp3 files. All subdirectories
|
6
|
+
# below indicated directory will be searched.
|
7
|
+
#
|
8
|
+
# == Usage
|
9
|
+
#
|
10
|
+
# podcast --dir my/mp3/dir --out podcast.rss
|
11
|
+
#
|
12
|
+
# == Author
|
13
|
+
# Ed Summers <ehs@pobox.com>
|
14
|
+
#
|
15
|
+
# == Copyright
|
16
|
+
# Copyright (c) 2004 Ed Summers.
|
17
|
+
# Licensed under the same terms as Ruby.
|
4
18
|
|
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
19
|
require 'optparse'
|
20
|
+
require 'rdoc/usage'
|
25
21
|
require 'rubygems'
|
26
22
|
require_gem 'podcast'
|
27
23
|
|
28
|
-
#
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
24
|
+
# the location to look for mp3s
|
25
|
+
dir = ''
|
26
|
+
|
27
|
+
# the location to write the podcast file
|
28
|
+
podcast_file = nil
|
33
29
|
|
34
30
|
# read options
|
35
31
|
opts = OptionParser.new
|
36
|
-
opts.on( "-d", "--dir VAL", String ) { |val|
|
37
|
-
opts.on( "-
|
38
|
-
opts.
|
39
|
-
|
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
|
32
|
+
opts.on( "-d", "--dir VAL", String ) { |val| dir=val }
|
33
|
+
opts.on( "-o", "--out VAL", String ) { |val| podcast_file=val }
|
34
|
+
opts.parse(ARGV) rescue RDoc::usage( 'usage' )
|
35
|
+
RDoc::usage( 'usage' ) if dir == ''
|
48
36
|
|
49
37
|
# create podcast object
|
50
|
-
podcast = Podcast.new()
|
51
|
-
podcast.base = options.base
|
52
|
-
podcast.title = options.title
|
38
|
+
podcast = Podcast::Feed.new()
|
53
39
|
|
54
40
|
# add a directory
|
55
|
-
podcast.add_dir(
|
41
|
+
podcast.add_dir( dir )
|
56
42
|
|
57
43
|
# write off the rss
|
58
|
-
if
|
59
|
-
file = File.new(
|
44
|
+
if podcast_file
|
45
|
+
file = File.new( podcast_file, 'w' )
|
60
46
|
file.write( podcast.get_rss() )
|
61
47
|
file.close
|
62
48
|
else
|
63
49
|
puts podcast.get_rss()
|
64
50
|
end
|
65
|
-
|
data/lib/podcast.rb
CHANGED
@@ -1,102 +1,116 @@
|
|
1
1
|
require 'find'
|
2
2
|
require 'rss/0.9'
|
3
|
-
require '
|
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
|
3
|
+
require 'mp3info'
|
29
4
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
@mp3s.push( mp3 )
|
34
|
-
end
|
5
|
+
module Podcast
|
6
|
+
|
7
|
+
class Feed
|
35
8
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
9
|
+
attr_reader :title, :link, :description, :image, :base, :language
|
10
|
+
attr_writer :title, :link, :description, :image, :base, :language
|
11
|
+
|
12
|
+
include Enumerable
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
@mp3s = []
|
16
|
+
@language = "English"
|
17
|
+
@base = ''
|
18
|
+
end
|
19
|
+
|
20
|
+
# add an mp3 file to the podcast
|
21
|
+
def add_mp3( file )
|
22
|
+
mp3 = Mp3File.new( file )
|
23
|
+
@mp3s.push( mp3 )
|
24
|
+
end
|
25
|
+
|
26
|
+
# add a directory location to the podcast
|
27
|
+
# the directory will be recursively search
|
28
|
+
# for mp3 files.
|
29
|
+
def add_dir( dir )
|
30
|
+
# we chdir into the directory so that file paths will be relative
|
31
|
+
pwd = Dir.pwd
|
32
|
+
Dir.chdir( dir )
|
33
|
+
Find.find( '.' ) do |f|
|
34
|
+
if ( f =~ /\.mp3$/ )
|
35
|
+
f.sub!( %r{^./}, '' ) # remove leading './'
|
36
|
+
add_mp3(f)
|
37
|
+
end
|
47
38
|
end
|
39
|
+
# go back to original directory
|
40
|
+
Dir.chdir( pwd )
|
48
41
|
end
|
49
|
-
# go back to original directory
|
50
|
-
Dir.chdir( pwd )
|
51
|
-
end
|
52
42
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
43
|
+
# the total amount of files in the podcast
|
44
|
+
def size
|
45
|
+
@mp3s.size
|
46
|
+
end
|
47
|
+
|
48
|
+
# write the podcast file
|
49
|
+
def get_rss()
|
50
|
+
rss = RSS::Rss.new( "0.9" )
|
51
|
+
channel = RSS::Rss::Channel.new
|
52
|
+
channel.title = @title
|
53
|
+
channel.description = @description
|
54
|
+
channel.link = @link
|
55
|
+
channel.language = @language
|
56
|
+
rss.channel = channel
|
57
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
58
|
image = RSS::Rss::Channel::Image.new
|
70
59
|
image.url = @image
|
71
60
|
image.title = @title
|
72
61
|
image.link = @link
|
73
62
|
channel.image = image
|
63
|
+
|
64
|
+
for mp3 in @mp3s
|
65
|
+
next if ! mp3.artist
|
66
|
+
item = RSS::Rss::Channel::Item.new
|
67
|
+
item.title = mp3
|
68
|
+
## add a base url
|
69
|
+
if base != ''
|
70
|
+
link = base + '/' + mp3.path
|
71
|
+
else
|
72
|
+
link = mp3.path
|
73
|
+
end
|
74
|
+
item.link = link
|
75
|
+
item.enclosure = RSS::Rss::Channel::Item::Enclosure.new(
|
76
|
+
link, mp3.length, mp3.type )
|
77
|
+
channel.items << item
|
78
|
+
end
|
79
|
+
|
80
|
+
return rss.to_s
|
74
81
|
end
|
75
82
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
item.title = mp3
|
80
|
-
## add a base url
|
81
|
-
if base != ''
|
82
|
-
link = base + '/' + mp3.path
|
83
|
-
else
|
84
|
-
link = mp3.path
|
83
|
+
def each
|
84
|
+
@songs.each do |s|
|
85
|
+
yield s
|
85
86
|
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
87
|
end
|
91
88
|
|
92
|
-
return rss.to_s
|
93
89
|
end
|
94
90
|
|
95
|
-
|
96
|
-
|
97
|
-
|
91
|
+
class Mp3File
|
92
|
+
|
93
|
+
attr_reader :artist, :album, :title, :file, :path, :length, :type, :mtime
|
94
|
+
attr_writer :artist, :album, :title, :file, :path, :length, :type, :mtime
|
95
|
+
|
96
|
+
def initialize(f)
|
97
|
+
file = File.new(f)
|
98
|
+
info = Mp3Info.open(f)
|
99
|
+
tag = info.tag()
|
100
|
+
@file = f
|
101
|
+
@artist = tag['artist']
|
102
|
+
@album = tag['album']
|
103
|
+
@title = tag['title']
|
104
|
+
@path = file.path()
|
105
|
+
@length = file.stat.size()
|
106
|
+
@mtime = file.stat.mtime()
|
107
|
+
@type = 'audio/mpeg'
|
108
|
+
end
|
109
|
+
|
110
|
+
def to_s
|
111
|
+
"#{@artist} -- #{@album} -- #{@title}"
|
98
112
|
end
|
113
|
+
|
99
114
|
end
|
100
115
|
|
101
116
|
end
|
102
|
-
|
@@ -1,47 +1,47 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
|
3
|
+
$LOAD_PATH.unshift('lib')
|
4
4
|
require 'test/unit'
|
5
5
|
require 'podcast'
|
6
6
|
|
7
7
|
class PodcastTest < Test::Unit::TestCase
|
8
8
|
|
9
9
|
def test_constructor
|
10
|
-
p = Podcast.new
|
11
|
-
assert(
|
10
|
+
p = Podcast::Feed.new
|
11
|
+
assert(p.class == Podcast::Feed)
|
12
12
|
end
|
13
13
|
|
14
14
|
def test_add_mp3
|
15
|
-
p = Podcast.new
|
16
|
-
p.add_mp3(
|
17
|
-
p.add_mp3(
|
18
|
-
p.add_mp3(
|
19
|
-
assert_equal(
|
15
|
+
p = Podcast::Feed.new
|
16
|
+
p.add_mp3('test/test.mp3')
|
17
|
+
p.add_mp3('test/test.mp3')
|
18
|
+
p.add_mp3('test/test.mp3')
|
19
|
+
assert_equal(p.size(), 3)
|
20
20
|
end
|
21
21
|
|
22
22
|
def test_add_dir
|
23
|
-
p = Podcast.new
|
24
|
-
p.add_dir(
|
25
|
-
assert_equal(
|
23
|
+
p = Podcast::Feed.new
|
24
|
+
p.add_dir('.')
|
25
|
+
assert_equal(p.size(), 1)
|
26
26
|
end
|
27
27
|
|
28
28
|
def test_get_rss
|
29
|
-
p = Podcast.new
|
29
|
+
p = Podcast::Feed.new
|
30
30
|
p.title = 'test podcast'
|
31
31
|
p.description = 'test podcast coming at ya'
|
32
32
|
p.link = 'http://www.example.org'
|
33
33
|
p.image = 'http://www.example.org/icon.png'
|
34
34
|
p.base = 'http://www.example.org/torrents'
|
35
35
|
## add using directory so we can confirm it is stripped
|
36
|
-
p.add_dir(
|
36
|
+
p.add_dir('test')
|
37
37
|
xml = p.get_rss()
|
38
38
|
|
39
39
|
# parse the rss
|
40
|
-
parser = RSS::Parser.new(
|
41
|
-
rss = RSS::Parser.parse(
|
40
|
+
parser = RSS::Parser.new('0.9')
|
41
|
+
rss = RSS::Parser.parse(xml)
|
42
42
|
items = rss.items()
|
43
|
-
assert(
|
44
|
-
|
43
|
+
assert(items.size == 1)
|
44
|
+
assert_equal(items[0].link, 'http://www.example.org/torrents/test.mp3')
|
45
45
|
end
|
46
46
|
|
47
47
|
end
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.8.
|
2
|
+
rubygems_version: 0.8.11
|
3
3
|
specification_version: 1
|
4
4
|
name: podcast
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.0.
|
7
|
-
date:
|
6
|
+
version: 0.0.4
|
7
|
+
date: 2005-11-21 00:00:00 -06:00
|
8
8
|
summary: Create podcasts from MP3 files
|
9
9
|
require_paths:
|
10
10
|
- lib
|
11
|
-
author: Ed Summers
|
12
11
|
email: ehs@pobox.com
|
13
12
|
homepage: http://www.inkdroid.org
|
14
13
|
rubyforge_project:
|
@@ -25,15 +24,18 @@ required_ruby_version: !ruby/object:Gem::Version::Requirement
|
|
25
24
|
version: 0.0.0
|
26
25
|
version:
|
27
26
|
platform: ruby
|
27
|
+
signing_key:
|
28
|
+
cert_chain:
|
29
|
+
authors:
|
30
|
+
- Ed Summers
|
28
31
|
files:
|
29
32
|
- bin/podcast
|
30
|
-
- lib/mp3file.rb
|
31
33
|
- lib/podcast.rb
|
32
34
|
- test/test.mp3
|
33
|
-
- test/
|
35
|
+
- test/ts_podcast.rb
|
34
36
|
- README
|
35
37
|
test_files:
|
36
|
-
- test/
|
38
|
+
- test/ts_podcast.rb
|
37
39
|
rdoc_options: []
|
38
40
|
extra_rdoc_files:
|
39
41
|
- README
|
data/lib/mp3file.rb
DELETED
@@ -1,28 +0,0 @@
|
|
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
|
-
|