podcast 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
-
|