splattael-shoutcast_api 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +6 -4
- data/Rakefile +1 -1
- data/lib/shoutcast_api.rb +52 -4
- data/shoutcast_api.gemspec +1 -1
- data/test/test_xml.rb +6 -0
- metadata +1 -1
data/README.rdoc
CHANGED
@@ -20,12 +20,14 @@ Uses httparty and roxml for fetch and parsing data from http://yp.shoutcast.com/
|
|
20
20
|
|
21
21
|
== Command line
|
22
22
|
|
23
|
-
|
23
|
+
shoutcast_api lib/shoutcast_api.rb # Genres
|
24
24
|
|
25
|
-
|
26
|
-
|
25
|
+
shoutcast_api name=Chronix
|
26
|
+
shoutcast_api genre=metal br=128 mt=audio/mpeg
|
27
|
+
|
28
|
+
== Authors
|
29
|
+
* Peter Suschlik
|
27
30
|
|
28
31
|
== TODO
|
29
32
|
|
30
|
-
* Docs!
|
31
33
|
* command line options transformations
|
data/Rakefile
CHANGED
data/lib/shoutcast_api.rb
CHANGED
@@ -18,17 +18,41 @@ module Shoutcast
|
|
18
18
|
# Delegate module methods to +Fetcher+.
|
19
19
|
def_delegators :Fetcher, :genres, :search
|
20
20
|
|
21
|
+
# Talks to shoutcast.com.
|
21
22
|
class Fetcher
|
22
23
|
include HTTParty
|
23
24
|
base_uri "http://yp.shoutcast.com"
|
24
25
|
format :plain
|
25
26
|
|
27
|
+
# Fetch all genres defined at shoutcast.com.
|
28
|
+
#
|
29
|
+
# === Usage
|
30
|
+
#
|
31
|
+
# Fetcher.genres.each do |genre|
|
32
|
+
# p genre.name
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# See Genrelist or Genre
|
36
|
+
#
|
26
37
|
def self.genres
|
27
38
|
fetch do |xml|
|
28
39
|
Genrelist.from_xml xml
|
29
40
|
end
|
30
41
|
end
|
31
42
|
|
43
|
+
# Search for available stations.
|
44
|
+
#
|
45
|
+
# === Usage
|
46
|
+
#
|
47
|
+
# Fetcher.search(:name => "California", :br => 128, :mt => "audio/mpeg")
|
48
|
+
#
|
49
|
+
# === Search options
|
50
|
+
#
|
51
|
+
# * <tt>:name</tt> - Match station +name+
|
52
|
+
# * <tt>:br</tt> - Match +bitrate+
|
53
|
+
# * <tt>:mt</tt> - Match +media_type+
|
54
|
+
#
|
55
|
+
# See Stationlist or Station
|
32
56
|
def self.search(options={})
|
33
57
|
fetch(options) do |xml|
|
34
58
|
Stationlist.from_xml xml
|
@@ -37,7 +61,7 @@ module Shoutcast
|
|
37
61
|
|
38
62
|
private
|
39
63
|
|
40
|
-
def self.fetch(options={}, &block)
|
64
|
+
def self.fetch(options={}, &block) # :nodoc:
|
41
65
|
options.update(:nocache => Time.now.to_f) if options
|
42
66
|
data = get("/sbin/newxml.phtml", :query => options).body
|
43
67
|
|
@@ -47,6 +71,7 @@ module Shoutcast
|
|
47
71
|
|
48
72
|
# XML
|
49
73
|
|
74
|
+
# Helper module. Include ROXML and defines some helper methods.
|
50
75
|
module Xml
|
51
76
|
def self.included(base)
|
52
77
|
base.send(:include, ROXML)
|
@@ -54,12 +79,16 @@ module Shoutcast
|
|
54
79
|
end
|
55
80
|
|
56
81
|
module ClassMethods
|
82
|
+
# Removes useless whitespaces.
|
57
83
|
def trim
|
58
84
|
proc { |v| v.to_s.strip.squeeze(" ") }
|
59
85
|
end
|
60
86
|
end
|
61
87
|
end
|
62
88
|
|
89
|
+
# Defines a shoutcast station.
|
90
|
+
#
|
91
|
+
# See Stationlist
|
63
92
|
class Station
|
64
93
|
include Xml
|
65
94
|
# <station
|
@@ -70,6 +99,8 @@ module Shoutcast
|
|
70
99
|
# genre="METAL"
|
71
100
|
# ct="TITLE"
|
72
101
|
# lc="24"/>
|
102
|
+
|
103
|
+
# URL ready to tune in.
|
73
104
|
attr_accessor :tunein
|
74
105
|
|
75
106
|
xml_reader :id, :from => :attr, :as => Integer
|
@@ -80,10 +111,13 @@ module Shoutcast
|
|
80
111
|
xml_reader :current_title, :from => '@ct', &trim
|
81
112
|
xml_reader :listeners, :from => '@lc', :as => Integer
|
82
113
|
|
114
|
+
# Get last part of +media_type+.
|
115
|
+
# Exmplae: <i>mpeg</i> for <i>audio/mpeg</i>
|
83
116
|
def type
|
84
117
|
media_type.split('/').last || media_type
|
85
118
|
end
|
86
119
|
|
120
|
+
# String representation of this station
|
87
121
|
def to_s
|
88
122
|
"#%10d %3d %40s %7d %50s" % [ id, bitrate, name[0...40], listeners, current_title[0...50] ]
|
89
123
|
end
|
@@ -92,6 +126,7 @@ module Shoutcast
|
|
92
126
|
"%11s %3s %-40s %7s %50s" % %w(id bit station-name listen. title)
|
93
127
|
end
|
94
128
|
|
129
|
+
# Compare by +listaners+ and +id+
|
95
130
|
def <=>(other)
|
96
131
|
result = listeners <=> other.listeners
|
97
132
|
result = id <=> other.id if result.zero?
|
@@ -99,6 +134,9 @@ module Shoutcast
|
|
99
134
|
end
|
100
135
|
end
|
101
136
|
|
137
|
+
# ist of stastons. Behaves like Array.
|
138
|
+
#
|
139
|
+
# See Station
|
102
140
|
class Stationlist
|
103
141
|
include Xml
|
104
142
|
extend Forwardable
|
@@ -107,7 +145,6 @@ module Shoutcast
|
|
107
145
|
|
108
146
|
# <tunein base="/sbin/tunein-station.pls"/>
|
109
147
|
# <station... /> <station .../>
|
110
|
-
|
111
148
|
xml_reader :tunein_base_path, :from => '@base', :in => 'tunein'
|
112
149
|
xml_attr :stations, :as => [ Station ]
|
113
150
|
|
@@ -116,27 +153,39 @@ module Shoutcast
|
|
116
153
|
end
|
117
154
|
self.base_uri = Fetcher.base_uri
|
118
155
|
|
156
|
+
# Returns url ready to tune in.
|
119
157
|
def tunein(station)
|
120
158
|
"#{self.class.base_uri}#{tunein_base_path}?id=#{station.id}"
|
121
159
|
end
|
122
160
|
|
123
161
|
private
|
124
162
|
|
125
|
-
|
163
|
+
# ROXML hook
|
164
|
+
def after_parse # :nodoc:
|
126
165
|
each { |station| station.tunein = tunein(station) }
|
127
166
|
end
|
128
167
|
end
|
129
168
|
|
169
|
+
# A music genre.
|
130
170
|
class Genre
|
131
171
|
include Xml
|
132
172
|
# <genre name="24h"/>
|
133
173
|
xml_reader :name, :from => :attr
|
134
174
|
|
175
|
+
# Compare by +name+
|
135
176
|
def <=>(other)
|
136
177
|
name <=> other.name
|
137
178
|
end
|
179
|
+
|
180
|
+
# String representation of this station
|
181
|
+
def to_s
|
182
|
+
name
|
183
|
+
end
|
138
184
|
end
|
139
185
|
|
186
|
+
# List of genres. Behaves like Array.
|
187
|
+
#
|
188
|
+
# See Genre
|
140
189
|
class Genrelist
|
141
190
|
include Xml
|
142
191
|
extend Forwardable
|
@@ -144,7 +193,6 @@ module Shoutcast
|
|
144
193
|
def_delegators :@genres, *(Array.instance_methods - instance_methods)
|
145
194
|
|
146
195
|
xml_attr :genres, :as => [ Genre ]
|
147
|
-
|
148
196
|
end
|
149
197
|
|
150
198
|
end
|
data/shoutcast_api.gemspec
CHANGED
data/test/test_xml.rb
CHANGED