shoutcast_api 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Manifest +13 -0
- data/README.rdoc +33 -0
- data/Rakefile +28 -0
- data/bin/shoutcast_search +35 -0
- data/lib/shoutcast_api.rb +196 -0
- data/shoutcast_api.gemspec +40 -0
- data/test/fixtures/empty.plain +0 -0
- data/test/fixtures/genrelist.plain +437 -0
- data/test/fixtures/search_death.plain +53 -0
- data/test/helper.rb +28 -0
- data/test/test_basic.rb +24 -0
- data/test/test_fetcher.rb +41 -0
- data/test/test_xml.rb +145 -0
- metadata +95 -0
data/Manifest
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
lib/shoutcast_api.rb
|
2
|
+
Rakefile
|
3
|
+
test/test_xml.rb
|
4
|
+
test/helper.rb
|
5
|
+
test/test_basic.rb
|
6
|
+
test/fixtures/empty.plain
|
7
|
+
test/fixtures/genrelist.plain
|
8
|
+
test/fixtures/search_death.plain
|
9
|
+
test/test_fetcher.rb
|
10
|
+
README.rdoc
|
11
|
+
Manifest
|
12
|
+
bin/shoutcast_search
|
13
|
+
shoutcast_api.gemspec
|
data/README.rdoc
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
= Shoutcast API
|
2
|
+
|
3
|
+
Simple API for http://shoutcast.com.
|
4
|
+
Uses httparty and roxml for fetching and parsing data from http://yp.shoutcast.com/sbin/newxml.phtml.
|
5
|
+
|
6
|
+
== Usage
|
7
|
+
|
8
|
+
require 'shoutcast_api'
|
9
|
+
|
10
|
+
# Stations
|
11
|
+
Shoutcast.search(:name => "Chronix").each do |station|
|
12
|
+
p station
|
13
|
+
puts station.tunein
|
14
|
+
end
|
15
|
+
|
16
|
+
Shoutcast.search(:genre => "Metal")
|
17
|
+
|
18
|
+
# Genres
|
19
|
+
Shoutcast.genres # => all genres
|
20
|
+
|
21
|
+
== Command line
|
22
|
+
|
23
|
+
shoutcast_api lib/shoutcast_api.rb # Genres
|
24
|
+
|
25
|
+
shoutcast_api name=Chronix
|
26
|
+
shoutcast_api genre=metal br=128 mt=audio/mpeg
|
27
|
+
|
28
|
+
== Authors
|
29
|
+
* Peter Suschlik
|
30
|
+
|
31
|
+
== TODO
|
32
|
+
|
33
|
+
* command line options transformations
|
data/Rakefile
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
|
5
|
+
desc 'Default: run unit tests.'
|
6
|
+
task :default => :test
|
7
|
+
|
8
|
+
require 'echoe'
|
9
|
+
Echoe.new('shoutcast_api') do |gem|
|
10
|
+
gem.version = '0.1.2'
|
11
|
+
gem.author = 'Peter Suschlik'
|
12
|
+
gem.summary = 'Simple shoutcast.com API.'
|
13
|
+
gem.email = 'peter-scapi@suschlik.de'
|
14
|
+
gem.url = %q{http://github.com/splattael/shoutcast_api}
|
15
|
+
gem.runtime_dependencies = [ "httparty ~>0.4", "roxml ~>2.5" ]
|
16
|
+
gem.ignore_pattern = ["tags"]
|
17
|
+
end
|
18
|
+
|
19
|
+
desc "Tag files for vim"
|
20
|
+
task :ctags do
|
21
|
+
dirs = $LOAD_PATH.select {|path| File.directory?(path) }
|
22
|
+
system "ctags -R #{dirs.join(" ")}"
|
23
|
+
end
|
24
|
+
|
25
|
+
desc "Find whitespace at line ends"
|
26
|
+
task :eol do
|
27
|
+
system "grep -nrE ' +$' *"
|
28
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Command line interface for shoutcast.com API.
|
4
|
+
# See documentation of Shoutcast for more information.
|
5
|
+
#
|
6
|
+
# === Usage
|
7
|
+
#
|
8
|
+
# shoutcast_search # => lists all genres
|
9
|
+
#
|
10
|
+
# shoutcast_search name=Chronix br=128 # => display a list of all Chronix stations with bitrate of 128
|
11
|
+
#
|
12
|
+
require 'rubygems'
|
13
|
+
|
14
|
+
require 'shoutcast_api'
|
15
|
+
|
16
|
+
if ARGV.size > 0
|
17
|
+
options = ARGV.inject({}) do |hash, arg|
|
18
|
+
key, value = arg.split(/=/)
|
19
|
+
hash[key.intern] = value
|
20
|
+
hash
|
21
|
+
end
|
22
|
+
# TODO do more transformations
|
23
|
+
# br -> bitrate
|
24
|
+
# ct -> current_title
|
25
|
+
# can ROXML help us?
|
26
|
+
options[:search] = options.delete(:name) if options[:name]
|
27
|
+
|
28
|
+
puts Shoutcast::Station.header
|
29
|
+
Shoutcast.search(options).sort.reverse.each do |station|
|
30
|
+
puts station
|
31
|
+
end
|
32
|
+
else
|
33
|
+
puts "Genres: ", Shoutcast.genres.map { |g| g.name }.join(", ")
|
34
|
+
end
|
35
|
+
|
@@ -0,0 +1,196 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
require 'roxml'
|
3
|
+
require 'forwardable'
|
4
|
+
|
5
|
+
#
|
6
|
+
# Simple API for http://shoutcast.com.
|
7
|
+
#
|
8
|
+
# === Usage
|
9
|
+
#
|
10
|
+
# Shoutcast.genres # => Genrelist
|
11
|
+
#
|
12
|
+
# Shoutcast.search(:search => "Metal", :br => 128) # => Stationlist
|
13
|
+
module Shoutcast
|
14
|
+
|
15
|
+
extend Forwardable
|
16
|
+
extend self
|
17
|
+
|
18
|
+
# Delegate module methods to +Fetcher+.
|
19
|
+
def_delegators :Fetcher, :genres, :search
|
20
|
+
|
21
|
+
# Talks to shoutcast.com.
|
22
|
+
class Fetcher
|
23
|
+
include HTTParty
|
24
|
+
base_uri "http://yp.shoutcast.com"
|
25
|
+
format :plain
|
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
|
+
#
|
37
|
+
def self.genres
|
38
|
+
fetch do |xml|
|
39
|
+
Genrelist.from_xml xml
|
40
|
+
end
|
41
|
+
end
|
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
|
56
|
+
def self.search(options={})
|
57
|
+
fetch(options) do |xml|
|
58
|
+
Stationlist.from_xml xml
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def self.fetch(options={}, &block) # :nodoc:
|
65
|
+
options.update(:nocache => Time.now.to_f) if options
|
66
|
+
data = get("/sbin/newxml.phtml", :query => options).body
|
67
|
+
|
68
|
+
block.call(data) unless data.empty?
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Helper module. Include ROXML and defines some helper methods.
|
73
|
+
module Xml
|
74
|
+
def self.included(base)
|
75
|
+
base.send(:include, ROXML)
|
76
|
+
base.extend ClassMethods
|
77
|
+
end
|
78
|
+
|
79
|
+
module ClassMethods
|
80
|
+
# Strip whitespaces.
|
81
|
+
def trim
|
82
|
+
proc { |v| v.to_s.strip.squeeze(" ") }
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Defines a shoutcast station.
|
88
|
+
#
|
89
|
+
# See Stationlist
|
90
|
+
class Station
|
91
|
+
include Xml
|
92
|
+
# <station
|
93
|
+
# id="423873"
|
94
|
+
# name="www.deathmetal.at"
|
95
|
+
# mt="audio/mpeg"
|
96
|
+
# br="128"
|
97
|
+
# genre="METAL"
|
98
|
+
# ct="TITLE"
|
99
|
+
# lc="24"/>
|
100
|
+
|
101
|
+
# URL ready to tune in.
|
102
|
+
attr_accessor :tunein
|
103
|
+
|
104
|
+
xml_reader :id, :from => :attr, :as => Integer
|
105
|
+
xml_reader :name, :from => :attr, &trim
|
106
|
+
xml_reader :media_type, :from => '@mt'
|
107
|
+
xml_reader :bitrate, :from => '@br', :as => Integer
|
108
|
+
xml_reader :genre, :from => :attr, &trim
|
109
|
+
xml_reader :current_title, :from => '@ct', &trim
|
110
|
+
xml_reader :listeners, :from => '@lc', :as => Integer
|
111
|
+
|
112
|
+
# Get last part of +media_type+.
|
113
|
+
# Example: <i>mpeg</i> for <i>audio/mpeg</i>
|
114
|
+
def type
|
115
|
+
media_type.split('/').last || media_type
|
116
|
+
end
|
117
|
+
|
118
|
+
# String representation of this station
|
119
|
+
def to_s
|
120
|
+
"#%10d %3d %40s %7d %50s" % [ id, bitrate, name[0...40], listeners, current_title[0...50] ]
|
121
|
+
end
|
122
|
+
|
123
|
+
def self.header
|
124
|
+
"%11s %3s %-40s %7s %50s" % %w(id bit station-name listen. title)
|
125
|
+
end
|
126
|
+
|
127
|
+
# Compare by +listeners+ and +id+
|
128
|
+
def <=>(other)
|
129
|
+
result = listeners <=> other.listeners
|
130
|
+
result = id <=> other.id if result.zero?
|
131
|
+
result
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
# A list of stations. Behaves like an Array.
|
136
|
+
#
|
137
|
+
# See Station
|
138
|
+
class Stationlist
|
139
|
+
include Xml
|
140
|
+
extend Forwardable
|
141
|
+
|
142
|
+
def_delegators :@stations, *(Array.instance_methods - instance_methods)
|
143
|
+
|
144
|
+
# <tunein base="/sbin/tunein-station.pls"/>
|
145
|
+
# <station... /> <station .../>
|
146
|
+
xml_reader :tunein_base_path, :from => '@base', :in => 'tunein'
|
147
|
+
xml_attr :stations, :as => [ Station ]
|
148
|
+
|
149
|
+
class << self
|
150
|
+
attr_accessor :base_uri
|
151
|
+
end
|
152
|
+
self.base_uri = Fetcher.base_uri
|
153
|
+
|
154
|
+
# Returns an url ready to tune in.
|
155
|
+
def tunein(station)
|
156
|
+
"#{self.class.base_uri}#{tunein_base_path}?id=#{station.id}"
|
157
|
+
end
|
158
|
+
|
159
|
+
private
|
160
|
+
|
161
|
+
# ROXML hook
|
162
|
+
def after_parse # :nodoc:
|
163
|
+
each { |station| station.tunein = tunein(station) }
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
# A music genre.
|
168
|
+
class Genre
|
169
|
+
include Xml
|
170
|
+
# <genre name="24h"/>
|
171
|
+
xml_reader :name, :from => :attr
|
172
|
+
|
173
|
+
# Compare by +name+
|
174
|
+
def <=>(other)
|
175
|
+
name <=> other.name
|
176
|
+
end
|
177
|
+
|
178
|
+
# String representation of this station
|
179
|
+
def to_s
|
180
|
+
name
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
# A list of genres. Behaves like an Array.
|
185
|
+
#
|
186
|
+
# See Genre
|
187
|
+
class Genrelist
|
188
|
+
include Xml
|
189
|
+
extend Forwardable
|
190
|
+
|
191
|
+
def_delegators :@genres, *(Array.instance_methods - instance_methods)
|
192
|
+
|
193
|
+
xml_attr :genres, :as => [ Genre ]
|
194
|
+
end
|
195
|
+
|
196
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{shoutcast_api}
|
5
|
+
s.version = "0.1.2"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Peter Suschlik"]
|
9
|
+
s.date = %q{2009-05-14}
|
10
|
+
s.default_executable = %q{shoutcast_search}
|
11
|
+
s.description = %q{Simple Shoutcast.com API.}
|
12
|
+
s.email = %q{peter-scapi@suschlik.de}
|
13
|
+
s.executables = ["shoutcast_search"]
|
14
|
+
s.extra_rdoc_files = ["bin/shoutcast_search", "lib/shoutcast_api.rb", "README.rdoc"]
|
15
|
+
s.files = ["Rakefile", "bin/shoutcast_search", "lib/shoutcast_api.rb", "README.rdoc", "Manifest", "test/test_xml.rb", "test/helper.rb", "test/test_fetcher.rb", "test/fixtures/genrelist.plain", "test/fixtures/search_death.plain", "test/fixtures/empty.plain", "test/test_basic.rb", "shoutcast_api.gemspec"]
|
16
|
+
s.has_rdoc = true
|
17
|
+
s.homepage = %q{http://github.com/splattael/shoutcast_api}
|
18
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Shoutcast_api", "--main", "README.rdoc"]
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
s.rubyforge_project = %q{shoutcast_api}
|
21
|
+
s.rubygems_version = %q{1.3.1}
|
22
|
+
s.summary = %q{Ruby API for Shoutcast.com.}
|
23
|
+
s.test_files = ["test/test_xml.rb", "test/test_fetcher.rb", "test/test_basic.rb"]
|
24
|
+
|
25
|
+
if s.respond_to? :specification_version then
|
26
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
27
|
+
s.specification_version = 2
|
28
|
+
|
29
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
30
|
+
s.add_runtime_dependency(%q<httparty>, ["~> 0.4"])
|
31
|
+
s.add_runtime_dependency(%q<roxml>, ["~> 2.5"])
|
32
|
+
else
|
33
|
+
s.add_dependency(%q<httparty>, ["~> 0.4"])
|
34
|
+
s.add_dependency(%q<roxml>, ["~> 2.5"])
|
35
|
+
end
|
36
|
+
else
|
37
|
+
s.add_dependency(%q<httparty>, ["~> 0.4"])
|
38
|
+
s.add_dependency(%q<roxml>, ["~> 2.5"])
|
39
|
+
end
|
40
|
+
end
|
File without changes
|
@@ -0,0 +1,437 @@
|
|
1
|
+
<?xml version="1.0" encoding='UTF-8' standalone="yes"?>
|
2
|
+
<genrelist>
|
3
|
+
<genre name="24h"></genre>
|
4
|
+
<genre name="24hs"></genre>
|
5
|
+
<genre name="40s"></genre>
|
6
|
+
<genre name="50s"></genre>
|
7
|
+
<genre name="60s"></genre>
|
8
|
+
<genre name="70s"></genre>
|
9
|
+
<genre name="80er"></genre>
|
10
|
+
<genre name="80s"></genre>
|
11
|
+
<genre name="90s"></genre>
|
12
|
+
<genre name="Acid"></genre>
|
13
|
+
<genre name="Adult"></genre>
|
14
|
+
<genre name="Adulto"></genre>
|
15
|
+
<genre name="African"></genre>
|
16
|
+
<genre name="Afro"></genre>
|
17
|
+
<genre name="Albanian"></genre>
|
18
|
+
<genre name="All"></genre>
|
19
|
+
<genre name="Alles"></genre>
|
20
|
+
<genre name="Alsong"></genre>
|
21
|
+
<genre name="Alt"></genre>
|
22
|
+
<genre name="Alternative"></genre>
|
23
|
+
<genre name="Alternativo"></genre>
|
24
|
+
<genre name="Amateur"></genre>
|
25
|
+
<genre name="Ambient"></genre>
|
26
|
+
<genre name="Americana"></genre>
|
27
|
+
<genre name="Anime"></genre>
|
28
|
+
<genre name="Anything"></genre>
|
29
|
+
<genre name="Arabesk"></genre>
|
30
|
+
<genre name="Arabic"></genre>
|
31
|
+
<genre name="Armenian"></genre>
|
32
|
+
<genre name="Art"></genre>
|
33
|
+
<genre name="Asia"></genre>
|
34
|
+
<genre name="Asian"></genre>
|
35
|
+
<genre name="Audio"></genre>
|
36
|
+
<genre name="Auto"></genre>
|
37
|
+
<genre name="Autopilot"></genre>
|
38
|
+
<genre name="Bachata"></genre>
|
39
|
+
<genre name="Backup"></genre>
|
40
|
+
<genre name="Baladas"></genre>
|
41
|
+
<genre name="Balkan"></genre>
|
42
|
+
<genre name="Bangla"></genre>
|
43
|
+
<genre name="Beatles"></genre>
|
44
|
+
<genre name="Best"></genre>
|
45
|
+
<genre name="Bible"></genre>
|
46
|
+
<genre name="Big"></genre>
|
47
|
+
<genre name="Black"></genre>
|
48
|
+
<genre name="Bluegrass"></genre>
|
49
|
+
<genre name="Blues"></genre>
|
50
|
+
<genre name="Boleros"></genre>
|
51
|
+
<genre name="Bolivia"></genre>
|
52
|
+
<genre name="Bollywood"></genre>
|
53
|
+
<genre name="Bossa"></genre>
|
54
|
+
<genre name="Brazilian"></genre>
|
55
|
+
<genre name="Breakbeat"></genre>
|
56
|
+
<genre name="Breakcore"></genre>
|
57
|
+
<genre name="Breaks"></genre>
|
58
|
+
<genre name="Bulgarca"></genre>
|
59
|
+
<genre name="Business"></genre>
|
60
|
+
<genre name="C64"></genre>
|
61
|
+
<genre name="Campus"></genre>
|
62
|
+
<genre name="Campusradio"></genre>
|
63
|
+
<genre name="Canal"></genre>
|
64
|
+
<genre name="Caribbean"></genre>
|
65
|
+
<genre name="Cat"></genre>
|
66
|
+
<genre name="Catholic"></genre>
|
67
|
+
<genre name="Celtic"></genre>
|
68
|
+
<genre name="Chanson"></genre>
|
69
|
+
<genre name="Charts"></genre>
|
70
|
+
<genre name="Chill"></genre>
|
71
|
+
<genre name="Chillout"></genre>
|
72
|
+
<genre name="Chinese"></genre>
|
73
|
+
<genre name="Chr"></genre>
|
74
|
+
<genre name="Christian"></genre>
|
75
|
+
<genre name="Christmas"></genre>
|
76
|
+
<genre name="Clasic"></genre>
|
77
|
+
<genre name="Clasicos"></genre>
|
78
|
+
<genre name="Classic"></genre>
|
79
|
+
<genre name="Classical"></genre>
|
80
|
+
<genre name="Club"></genre>
|
81
|
+
<genre name="College"></genre>
|
82
|
+
<genre name="Comedy"></genre>
|
83
|
+
<genre name="Community"></genre>
|
84
|
+
<genre name="Compas"></genre>
|
85
|
+
<genre name="Contemporary"></genre>
|
86
|
+
<genre name="Country"></genre>
|
87
|
+
<genre name="Cristian"></genre>
|
88
|
+
<genre name="Cristiana"></genre>
|
89
|
+
<genre name="Cristiano"></genre>
|
90
|
+
<genre name="Croatia"></genre>
|
91
|
+
<genre name="Croatian"></genre>
|
92
|
+
<genre name="Cultura"></genre>
|
93
|
+
<genre name="Cultural"></genre>
|
94
|
+
<genre name="Culture"></genre>
|
95
|
+
<genre name="Cumbia"></genre>
|
96
|
+
<genre name="Damar"></genre>
|
97
|
+
<genre name="Dance"></genre>
|
98
|
+
<genre name="Dancefloor"></genre>
|
99
|
+
<genre name="Dancehall"></genre>
|
100
|
+
<genre name="Dark"></genre>
|
101
|
+
<genre name="Darkwave"></genre>
|
102
|
+
<genre name="Das"></genre>
|
103
|
+
<genre name="Death"></genre>
|
104
|
+
<genre name="Decades"></genre>
|
105
|
+
<genre name="Deep"></genre>
|
106
|
+
<genre name="Deportes"></genre>
|
107
|
+
<genre name="Der"></genre>
|
108
|
+
<genre name="Desi"></genre>
|
109
|
+
<genre name="Die"></genre>
|
110
|
+
<genre name="Dini"></genre>
|
111
|
+
<genre name="Dirty"></genre>
|
112
|
+
<genre name="Disco"></genre>
|
113
|
+
<genre name="Discofox"></genre>
|
114
|
+
<genre name="Disney"></genre>
|
115
|
+
<genre name="Diverse"></genre>
|
116
|
+
<genre name="Dnb"></genre>
|
117
|
+
<genre name="Domaca"></genre>
|
118
|
+
<genre name="Doowop"></genre>
|
119
|
+
<genre name="Downtempo"></genre>
|
120
|
+
<genre name="Drum"></genre>
|
121
|
+
<genre name="Dub"></genre>
|
122
|
+
<genre name="Dubstep"></genre>
|
123
|
+
<genre name="Dutch"></genre>
|
124
|
+
<genre name="Easy"></genre>
|
125
|
+
<genre name="Ebm"></genre>
|
126
|
+
<genre name="Ecl"></genre>
|
127
|
+
<genre name="Eclectic"></genre>
|
128
|
+
<genre name="Electro"></genre>
|
129
|
+
<genre name="Electronic"></genre>
|
130
|
+
<genre name="Electronica"></genre>
|
131
|
+
<genre name="Electronique"></genre>
|
132
|
+
<genre name="Elektro"></genre>
|
133
|
+
<genre name="Eletro"></genre>
|
134
|
+
<genre name="Emisora"></genre>
|
135
|
+
<genre name="Emo"></genre>
|
136
|
+
<genre name="Enfants"></genre>
|
137
|
+
<genre name="Espa"></genre>
|
138
|
+
<genre name="Euro"></genre>
|
139
|
+
<genre name="Eurodance"></genre>
|
140
|
+
<genre name="European"></genre>
|
141
|
+
<genre name="Evangelica"></genre>
|
142
|
+
<genre name="Everything"></genre>
|
143
|
+
<genre name="Exitos"></genre>
|
144
|
+
<genre name="Experimental"></genre>
|
145
|
+
<genre name="Family"></genre>
|
146
|
+
<genre name="Fantasy"></genre>
|
147
|
+
<genre name="Film"></genre>
|
148
|
+
<genre name="Fire"></genre>
|
149
|
+
<genre name="Flamenco"></genre>
|
150
|
+
<genre name="Folk"></genre>
|
151
|
+
<genre name="Folklore"></genre>
|
152
|
+
<genre name="Forr"></genre>
|
153
|
+
<genre name="Forro"></genre>
|
154
|
+
<genre name="Fox"></genre>
|
155
|
+
<genre name="Francais"></genre>
|
156
|
+
<genre name="Free"></genre>
|
157
|
+
<genre name="Freeform"></genre>
|
158
|
+
<genre name="Freestyle"></genre>
|
159
|
+
<genre name="French"></genre>
|
160
|
+
<genre name="Fresh"></genre>
|
161
|
+
<genre name="Full"></genre>
|
162
|
+
<genre name="Funk"></genre>
|
163
|
+
<genre name="Funky"></genre>
|
164
|
+
<genre name="Game"></genre>
|
165
|
+
<genre name="Garage"></genre>
|
166
|
+
<genre name="Gay"></genre>
|
167
|
+
<genre name="Gemischt"></genre>
|
168
|
+
<genre name="General"></genre>
|
169
|
+
<genre name="Generaliste"></genre>
|
170
|
+
<genre name="Genero"></genre>
|
171
|
+
<genre name="Genre"></genre>
|
172
|
+
<genre name="German"></genre>
|
173
|
+
<genre name="Ghana"></genre>
|
174
|
+
<genre name="Goa"></genre>
|
175
|
+
<genre name="Gold"></genre>
|
176
|
+
<genre name="Golden"></genre>
|
177
|
+
<genre name="Good"></genre>
|
178
|
+
<genre name="Gospel"></genre>
|
179
|
+
<genre name="Goth"></genre>
|
180
|
+
<genre name="Gothic"></genre>
|
181
|
+
<genre name="Gra"></genre>
|
182
|
+
<genre name="Greece"></genre>
|
183
|
+
<genre name="Greek"></genre>
|
184
|
+
<genre name="Grupero"></genre>
|
185
|
+
<genre name="Haiti"></genre>
|
186
|
+
<genre name="Haitian"></genre>
|
187
|
+
<genre name="Halk"></genre>
|
188
|
+
<genre name="Ham"></genre>
|
189
|
+
<genre name="Hands"></genre>
|
190
|
+
<genre name="Handsup"></genre>
|
191
|
+
<genre name="Happy"></genre>
|
192
|
+
<genre name="Hard"></genre>
|
193
|
+
<genre name="Hardcore"></genre>
|
194
|
+
<genre name="Hardstyle"></genre>
|
195
|
+
<genre name="Hardtechno"></genre>
|
196
|
+
<genre name="Hbwa"></genre>
|
197
|
+
<genre name="Heavy"></genre>
|
198
|
+
<genre name="Her"></genre>
|
199
|
+
<genre name="High"></genre>
|
200
|
+
<genre name="Hindi"></genre>
|
201
|
+
<genre name="Hip"></genre>
|
202
|
+
<genre name="Hiphop"></genre>
|
203
|
+
<genre name="Hit"></genre>
|
204
|
+
<genre name="Hits"></genre>
|
205
|
+
<genre name="Holiday"></genre>
|
206
|
+
<genre name="Hollands"></genre>
|
207
|
+
<genre name="Hollandse"></genre>
|
208
|
+
<genre name="Hot"></genre>
|
209
|
+
<genre name="House"></genre>
|
210
|
+
<genre name="Hoy"></genre>
|
211
|
+
<genre name="Hrvatska"></genre>
|
212
|
+
<genre name="Http"></genre>
|
213
|
+
<genre name="Hungarian"></genre>
|
214
|
+
<genre name="Hungaryan"></genre>
|
215
|
+
<genre name="Idm"></genre>
|
216
|
+
<genre name="Independent"></genre>
|
217
|
+
<genre name="Indian"></genre>
|
218
|
+
<genre name="Indie"></genre>
|
219
|
+
<genre name="Indonesia"></genre>
|
220
|
+
<genre name="Industrial"></genre>
|
221
|
+
<genre name="Infantil"></genre>
|
222
|
+
<genre name="Info"></genre>
|
223
|
+
<genre name="Informaci"></genre>
|
224
|
+
<genre name="Informacion"></genre>
|
225
|
+
<genre name="Inspirational"></genre>
|
226
|
+
<genre name="Instrumental"></genre>
|
227
|
+
<genre name="International"></genre>
|
228
|
+
<genre name="Islam"></genre>
|
229
|
+
<genre name="Italian"></genre>
|
230
|
+
<genre name="Italiana"></genre>
|
231
|
+
<genre name="Italo"></genre>
|
232
|
+
<genre name="Japan"></genre>
|
233
|
+
<genre name="Japanese"></genre>
|
234
|
+
<genre name="Jazz"></genre>
|
235
|
+
<genre name="Jazzy"></genre>
|
236
|
+
<genre name="Jewish"></genre>
|
237
|
+
<genre name="Jornalismo"></genre>
|
238
|
+
<genre name="Jovem"></genre>
|
239
|
+
<genre name="Jpop"></genre>
|
240
|
+
<genre name="Jump"></genre>
|
241
|
+
<genre name="Jumpstyle"></genre>
|
242
|
+
<genre name="Jungle"></genre>
|
243
|
+
<genre name="Juvenil"></genre>
|
244
|
+
<genre name="Kar"></genre>
|
245
|
+
<genre name="Khmer"></genre>
|
246
|
+
<genre name="Kizomba"></genre>
|
247
|
+
<genre name="Laika"></genre>
|
248
|
+
<genre name="Latin"></genre>
|
249
|
+
<genre name="Latina"></genre>
|
250
|
+
<genre name="Latino"></genre>
|
251
|
+
<genre name="Life"></genre>
|
252
|
+
<genre name="Light"></genre>
|
253
|
+
<genre name="Live"></genre>
|
254
|
+
<genre name="Local"></genre>
|
255
|
+
<genre name="Lokaal"></genre>
|
256
|
+
<genre name="Lokale"></genre>
|
257
|
+
<genre name="Lounge"></genre>
|
258
|
+
<genre name="Love"></genre>
|
259
|
+
<genre name="Low"></genre>
|
260
|
+
<genre name="Main"></genre>
|
261
|
+
<genre name="Mainstream"></genre>
|
262
|
+
<genre name="Makina"></genre>
|
263
|
+
<genre name="Malaysia"></genre>
|
264
|
+
<genre name="Manele"></genre>
|
265
|
+
<genre name="Mdr"></genre>
|
266
|
+
<genre name="Mega"></genre>
|
267
|
+
<genre name="Melodic"></genre>
|
268
|
+
<genre name="Merengue"></genre>
|
269
|
+
<genre name="Metal"></genre>
|
270
|
+
<genre name="Mexican"></genre>
|
271
|
+
<genre name="Minimal"></genre>
|
272
|
+
<genre name="Mix"></genre>
|
273
|
+
<genre name="Mixed"></genre>
|
274
|
+
<genre name="Mixes"></genre>
|
275
|
+
<genre name="Modern"></genre>
|
276
|
+
<genre name="Music"></genre>
|
277
|
+
<genre name="Musica"></genre>
|
278
|
+
<genre name="Musical"></genre>
|
279
|
+
<genre name="Musik"></genre>
|
280
|
+
<genre name="Musique"></genre>
|
281
|
+
<genre name="Muzica"></genre>
|
282
|
+
<genre name="Muziek"></genre>
|
283
|
+
<genre name="Muzika"></genre>
|
284
|
+
<genre name="Muzyka"></genre>
|
285
|
+
<genre name="Narodna"></genre>
|
286
|
+
<genre name="Native"></genre>
|
287
|
+
<genre name="Ned"></genre>
|
288
|
+
<genre name="Nederlands"></genre>
|
289
|
+
<genre name="Nederlandse"></genre>
|
290
|
+
<genre name="Nederlandstalig"></genre>
|
291
|
+
<genre name="New"></genre>
|
292
|
+
<genre name="Newage"></genre>
|
293
|
+
<genre name="News"></genre>
|
294
|
+
<genre name="Nigerian"></genre>
|
295
|
+
<genre name="Non"></genre>
|
296
|
+
<genre name="Nonstop"></genre>
|
297
|
+
<genre name="Noticias"></genre>
|
298
|
+
<genre name="Npr"></genre>
|
299
|
+
<genre name="Old"></genre>
|
300
|
+
<genre name="Oldies"></genre>
|
301
|
+
<genre name="Oldschool"></genre>
|
302
|
+
<genre name="Oldskool"></genre>
|
303
|
+
<genre name="Online"></genre>
|
304
|
+
<genre name="Only"></genre>
|
305
|
+
<genre name="Orthodox"></genre>
|
306
|
+
<genre name="Other"></genre>
|
307
|
+
<genre name="Ozgun"></genre>
|
308
|
+
<genre name="Para"></genre>
|
309
|
+
<genre name="Paranormal"></genre>
|
310
|
+
<genre name="Party"></genre>
|
311
|
+
<genre name="Period"></genre>
|
312
|
+
<genre name="Persian"></genre>
|
313
|
+
<genre name="Pilot"></genre>
|
314
|
+
<genre name="Pinoy"></genre>
|
315
|
+
<genre name="Piraat"></genre>
|
316
|
+
<genre name="Pirate"></genre>
|
317
|
+
<genre name="Piraten"></genre>
|
318
|
+
<genre name="Piratenhits"></genre>
|
319
|
+
<genre name="Playlist"></genre>
|
320
|
+
<genre name="Political"></genre>
|
321
|
+
<genre name="Polska"></genre>
|
322
|
+
<genre name="Polskie"></genre>
|
323
|
+
<genre name="Pop"></genre>
|
324
|
+
<genre name="Popular"></genre>
|
325
|
+
<genre name="Populara"></genre>
|
326
|
+
<genre name="Por"></genre>
|
327
|
+
<genre name="Portuguese"></genre>
|
328
|
+
<genre name="Praise"></genre>
|
329
|
+
<genre name="Private"></genre>
|
330
|
+
<genre name="Prog"></genre>
|
331
|
+
<genre name="Progressive"></genre>
|
332
|
+
<genre name="Psy"></genre>
|
333
|
+
<genre name="Psychedelic"></genre>
|
334
|
+
<genre name="Psytrance"></genre>
|
335
|
+
<genre name="Public"></genre>
|
336
|
+
<genre name="Punjabi"></genre>
|
337
|
+
<genre name="Punk"></genre>
|
338
|
+
<genre name="Pure"></genre>
|
339
|
+
<genre name="R&b"></genre>
|
340
|
+
<genre name="Radio"></genre>
|
341
|
+
<genre name="Radiostation"></genre>
|
342
|
+
<genre name="Radyo"></genre>
|
343
|
+
<genre name="Railroad"></genre>
|
344
|
+
<genre name="Random"></genre>
|
345
|
+
<genre name="Rap"></genre>
|
346
|
+
<genre name="Reggae"></genre>
|
347
|
+
<genre name="Reggaeton"></genre>
|
348
|
+
<genre name="Regional"></genre>
|
349
|
+
<genre name="Relax"></genre>
|
350
|
+
<genre name="Religious"></genre>
|
351
|
+
<genre name="Retro"></genre>
|
352
|
+
<genre name="Rhythmic"></genre>
|
353
|
+
<genre name="Rnb"></genre>
|
354
|
+
<genre name="Rock"></genre>
|
355
|
+
<genre name="Rom"></genre>
|
356
|
+
<genre name="Romaneasca"></genre>
|
357
|
+
<genre name="Romania"></genre>
|
358
|
+
<genre name="Romanian"></genre>
|
359
|
+
<genre name="Romantic"></genre>
|
360
|
+
<genre name="Roots"></genre>
|
361
|
+
<genre name="Russian"></genre>
|
362
|
+
<genre name="Salsa"></genre>
|
363
|
+
<genre name="Scanner"></genre>
|
364
|
+
<genre name="Schlager"></genre>
|
365
|
+
<genre name="Scouse"></genre>
|
366
|
+
<genre name="Sega"></genre>
|
367
|
+
<genre name="Sertanejo"></genre>
|
368
|
+
<genre name="Shortwave"></genre>
|
369
|
+
<genre name="Shqip"></genre>
|
370
|
+
<genre name="Sinhala"></genre>
|
371
|
+
<genre name="Ska"></genre>
|
372
|
+
<genre name="Slow"></genre>
|
373
|
+
<genre name="Smooth"></genre>
|
374
|
+
<genre name="Soca"></genre>
|
375
|
+
<genre name="Soft"></genre>
|
376
|
+
<genre name="Solo"></genre>
|
377
|
+
<genre name="Soul"></genre>
|
378
|
+
<genre name="Soundtrack"></genre>
|
379
|
+
<genre name="Soundtracks"></genre>
|
380
|
+
<genre name="Southern"></genre>
|
381
|
+
<genre name="Space"></genre>
|
382
|
+
<genre name="Spain"></genre>
|
383
|
+
<genre name="Spanish"></genre>
|
384
|
+
<genre name="Spiritual"></genre>
|
385
|
+
<genre name="Spoken"></genre>
|
386
|
+
<genre name="Sport"></genre>
|
387
|
+
<genre name="Sports"></genre>
|
388
|
+
<genre name="Student"></genre>
|
389
|
+
<genre name="Studio"></genre>
|
390
|
+
<genre name="Super"></genre>
|
391
|
+
<genre name="Synthpop"></genre>
|
392
|
+
<genre name="Talk"></genre>
|
393
|
+
<genre name="Tamil"></genre>
|
394
|
+
<genre name="Tango"></genre>
|
395
|
+
<genre name="Tech"></genre>
|
396
|
+
<genre name="Techno"></genre>
|
397
|
+
<genre name="Test"></genre>
|
398
|
+
<genre name="Thai"></genre>
|
399
|
+
<genre name="The"></genre>
|
400
|
+
<genre name="Toca"></genre>
|
401
|
+
<genre name="Todo"></genre>
|
402
|
+
<genre name="Todos"></genre>
|
403
|
+
<genre name="Top"></genre>
|
404
|
+
<genre name="Top40"></genre>
|
405
|
+
<genre name="Total"></genre>
|
406
|
+
<genre name="Trance"></genre>
|
407
|
+
<genre name="Tropical"></genre>
|
408
|
+
<genre name="Trova"></genre>
|
409
|
+
<genre name="Turk"></genre>
|
410
|
+
<genre name="Turkce"></genre>
|
411
|
+
<genre name="Turkish"></genre>
|
412
|
+
<genre name="Tylko"></genre>
|
413
|
+
<genre name="Underground"></genre>
|
414
|
+
<genre name="Universal"></genre>
|
415
|
+
<genre name="Unsigned"></genre>
|
416
|
+
<genre name="Urban"></genre>
|
417
|
+
<genre name="Van"></genre>
|
418
|
+
<genre name="Vari"></genre>
|
419
|
+
<genre name="Variada"></genre>
|
420
|
+
<genre name="Variado"></genre>
|
421
|
+
<genre name="Varied"></genre>
|
422
|
+
<genre name="Variety"></genre>
|
423
|
+
<genre name="Varios"></genre>
|
424
|
+
<genre name="Various"></genre>
|
425
|
+
<genre name="Vedic"></genre>
|
426
|
+
<genre name="Video"></genre>
|
427
|
+
<genre name="Vocal"></genre>
|
428
|
+
<genre name="Web"></genre>
|
429
|
+
<genre name="Wir"></genre>
|
430
|
+
<genre name="World"></genre>
|
431
|
+
<genre name="Wusf"></genre>
|
432
|
+
<genre name="Www"></genre>
|
433
|
+
<genre name="Xltrax"></genre>
|
434
|
+
<genre name="Yabanci"></genre>
|
435
|
+
<genre name="Zabavna"></genre>
|
436
|
+
<genre name="Zouk"></genre>
|
437
|
+
</genrelist>
|
@@ -0,0 +1,53 @@
|
|
1
|
+
<?xml version="1.0" encoding='UTF-8' ?>
|
2
|
+
<stationlist>
|
3
|
+
<tunein base="/sbin/tunein-station.pls"></tunein>
|
4
|
+
<station name="METAL-ONLY - www.metal-only.de - 24h Black Death Heavy Metal Rock und mehr!" mt="audio/mpeg" id="4596" br="112" genre="METAL ROCK ALTERNATIVE" ct="* Wolle OnAir * Folk-, Mittelalter-, Pagan-, Vikingmetal *" lc="617"></station>
|
5
|
+
<station name="Death.F(ucking)M(etal) - A Brutal & Beautiful Blend of Black, Death, Goth, Gore & Grind w/Requests" mt="audio/aacp" id="447542" br="64" genre="Metal Black Death Doom" ct="Bilocate - Sudden Death Syndrome - Ebtehal (9:25)" lc="98"></station>
|
6
|
+
<station name="Death.F(ucking)M(etal) - A Brutal & Beautiful Blend of Black, Death, Goth, Gore & Grind w/Requests" mt="audio/mpeg" id="297093" br="32" genre="Metal Black Death Doom" ct="Bilocate - Sudden Death Syndrome - Ebtehal (9:25)" lc="37"></station>
|
7
|
+
<station name="SomaFM presents: Indie Pop Rocks! [SomaFM]" mt="audio/mpeg" id="61130" br="24" genre="Indie LoFi College" ct="Death Cab For Cutie - World Shut Your Mouth" lc="35"></station>
|
8
|
+
<station name="Autoslinga" mt="audio/mpeg" id="7607" br="128" genre="All" ct="The Notorious B.I.G. - Life After Death (Disc 2) - Miss U" lc="30"></station>
|
9
|
+
<station name="www.deathmetal.at [DEATHMETAL - DEATHCORE - BRUTAL DEATH - GORE GRIND - GRINDCORE]" mt="audio/mpeg" id="423873" br="128" genre="METAL DEATHMETAL " ct="brain drill - sadistic abductive" lc="25"></station>
|
10
|
+
<station name="GotRadio - Alternaitve" mt="audio/mpeg" id="5747" br="128" genre="Alternative Rock Colleg" ct="Death Cab For Cutie - I Will Possess Your Heart (edit)" lc="22"></station>
|
11
|
+
<station name="Altared Lives Radio" mt="audio/mpeg" id="707614" br="64" genre="Rap Christian hip hop R" ct="Raptillion - Death of My Ministry" lc="21"></station>
|
12
|
+
<station name="H4XED Metal - The newest Melodic, Death, and Thrash Metal!" mt="audio/mpeg" id="897597" br="160" genre="Melodic Death Metal Thra" ct="Double Dragon - Beneath the City of Churches" lc="19"></station>
|
13
|
+
<station name="killedbydeath.org -- only the finest raw punk crap you've not heard of. if they're famous, they won'" mt="audio/mpeg" id="304237" br="128" genre="Punk Alternative" ct="Discharge - Cries Of Help - Protest And Survive disk 1" lc="15"></station>
|
14
|
+
<station name="MELTED METAL.COM ::: 24/7 SCORCHING HARD ROCK ::: (Metallica, Deathcore, Alternative, Progressive)" mt="audio/mpeg" id="182777" br="128" genre="Metal Industrial" ct="New Breed - Red" lc="12"></station>
|
15
|
+
<station name="Wolf Lair Radio WOLFLAIRRADIO NSBM Black Metal Death Metal Pagan Metal Elegy" mt="audio/mpeg" id="514056" br="128" genre="NSBM Death metal Black Me" ct="Venom - Bursting Out" lc="12"></station>
|
16
|
+
<station name="DEATHLORD" mt="audio/mpeg" id="596037" br="128" genre="torrentkiller " ct="Tom Novy feat Michael Marshall - Your body (andy)" lc="11"></station>
|
17
|
+
<station name="FreshRadio | Auto DJ - **Advertise here** Call 1(876)439-6460" mt="audio/mpeg" id="951311" br="96" genre="Dancehall Reggae Soca" ct="[Chinese Assassin] Death_of_A_Samurai-23.04" lc="11"></station>
|
18
|
+
<station name="Hardcore, Speedcore, Breakcore Radio" mt="audio/mpeg" id="665036" br="128" genre="Hardcore Breakcore Speedc" ct="VA - Deathmachine Vs Producer - Liv" lc="9"></station>
|
19
|
+
<station name="Baphometus Revelatum Radio" mt="audio/mpeg" id="337104" br="128" genre="Death Metal Black Metal" ct="Shroud Of Despondency - Untouchable Comfort In The Knowle" lc="8"></station>
|
20
|
+
<station name="Radio Umbria .com, tu radio oscura online" mt="audio/mpeg" id="604725" br="128" genre="goth" ct="Regenerator - Death (Return To Emptiness Mix By Neikka RPM)" lc="6"></station>
|
21
|
+
<station name="La mejor musica transmitida por dj ScRaPy_dOO 'Ablinux uniendo amigos...Sin fronteras!!!" mt="audio/mpeg" id="882295" br="24" genre="todos los generos" ct="Nightmare - Alumina (Death Note Ending)" lc="6"></station>
|
22
|
+
<station name="H4XED Metal - The newest Melodic, Death, and Thrash Metal!" mt="audio/aacp" id="612882" br="96" genre="Melodic Death Metal Thra" ct="Double Dragon - Beneath the City of Churches" lc="5"></station>
|
23
|
+
<station name="'radio.XES' - Metal, Rock & Death" mt="audio/mpeg" id="2517" br="128" genre="Metal Rock Death" ct="Trespassing - Everlasting" lc="4"></station>
|
24
|
+
<station name="~DJ-NOS~@xxxtremefullthrottleradio" mt="audio/mpeg" id="251692" br="64" genre="Metal" ct="Five Finger Death Punch - A Place To Die" lc="4"></station>
|
25
|
+
<station name="Death.F(ucking)M(etal) - A Brutal & Beautiful Blend of Black, Death, Goth, Gore & Grind w/Requests" mt="audio/aacp" id="914291" br="32" genre="Metal Black Death Doom" ct="Bilocate - Sudden Death Syndrome - Ebtehal (9:25)" lc="4"></station>
|
26
|
+
<station name="SpacialNet: Toon Radio" mt="audio/mpeg" id="35038" br="64" genre="Soundtrack anime" ct="Saeko Chiba - Club-to-Death Angel Dokuro-chan (Rurutie - Mix)" lc="3"></station>
|
27
|
+
<station name="SKULLMETAL RADIO / DJ ESOTERIC DEATH / METAL MORNING SHOW" mt="audio/mpeg" id="487667" br="128" genre="Metal" ct="Death - In Human Form" lc="3"></station>
|
28
|
+
<station name="* Szekely Radio * Szekelyudvarhely" mt="audio/aacp" id="683194" br="32" genre="Szekelyfold" ct="Iggy Pop - In The Deathcar" lc="3"></station>
|
29
|
+
<station name="JFL Metal ~ Brutal Radio for the Metal Horde ~" mt="audio/mpeg" id="925171" br="96" genre="Death Thrash Black Folk" ct="Carcass - Black Star" lc="3"></station>
|
30
|
+
<station name="Violent Forces Radio" mt="audio/mpeg" id="479974" br="128" genre="Metal Thrash Metal De" ct="Nuclear Death Terror - Chaotic Alliance" lc="2"></station>
|
31
|
+
<station name="Dj Bootylious@ Booty's Blue Rose" mt="audio/mpeg" id="709413" br="96" genre="Various" ct="Five Finger Death Punch - Never Enough - Album Version" lc="2"></station>
|
32
|
+
<station name="Rock Remakes" mt="audio/mpeg" id="775059" br="96" genre="Rock" ct="Dublin Death Patrol - Cold Sweat (Thin Lizzy)" lc="2"></station>
|
33
|
+
<station name="Radio Fantasy-dream.de" mt="audio/mpeg" id="26682" br="128" genre="International" ct="Him - Join Me in Death" lc="1"></station>
|
34
|
+
<station name="RADIO BIZZZZZZZZZZZZZZZZZZZZ METAL X-TREM" mt="audio/mpeg" id="243499" br="96" genre="DEATH BLACK METAL" ct="Between the Buried and Me - Sun of Nothing" lc="1"></station>
|
35
|
+
<station name="SpacialNet: Firefly Radio - firefly.comze.com - Broadcasting on the Chill Wave - Tonite anything goe" mt="audio/mpeg" id="475280" br="64" genre="House" ct="Metal Church - Line of Death" lc="1"></station>
|
36
|
+
<station name="PumpUpTheBass-Indie Fusion: Indie Fusion" mt="audio/mpeg" id="489861" br="128" genre="Various" ct="Jimmy Lovelace - 01 Death In A Bottle" lc="1"></station>
|
37
|
+
<station name="Rock Nation Radio: Heavy, Thrash, Death, Black Metal" mt="audio/mpeg" id="652068" br="32" genre="Hard Rock Heavy Metal " ct="Gamma Ray - Last Before The Storm" lc="1"></station>
|
38
|
+
<station name="Rock Nation Radio 2: All Metal" mt="audio/mpeg" id="749794" br="128" genre="Heavy Thrash Death Bla" ct="Gamma Ray - Last Before The Storm" lc="1"></station>
|
39
|
+
<station name="RADIO DEATHLORD" mt="audio/mpeg" id="757844" br="128" genre="Various" ct="11 Liviu - Am dat lume de belea [www.ten28.com]" lc="1"></station>
|
40
|
+
<station name="My Station name" mt="audio/mpeg" id="898789" br="64" genre="X Factor Radio" ct="Eagles of Death Metal - Eagles Goth" lc="1"></station>
|
41
|
+
<station name="FSC Radio" mt="audio/mpeg" id="138719" br="64" genre="Miscellanous" ct="five finger death punch - salvation live" lc="0"></station>
|
42
|
+
<station name="Owned-Radio" mt="audio/mpeg" id="146334" br="128" genre="Mixed" ct="Five Finger Death Punch - The Way Of The Fist - White Knuckles" lc="0"></station>
|
43
|
+
<station name="GotRadio - Alternative" mt="audio/mpeg" id="254897" br="16" genre="Alternative Rock Rock" ct="Death Cab For Cutie - I Will Possess Your Heart (edit)" lc="0"></station>
|
44
|
+
<station name="Vitrolao Pan" mt="audio/mpeg" id="325205" br="64" genre="Jovem Ecletica " ct="Coldplay - Viva la Vida or Death and All His Friends - Viva la Vida" lc="0"></station>
|
45
|
+
<station name="Death Metal" mt="audio/mpeg" id="375381" br="80" genre="Brutal Metal" ct="Immortal - 05 - Within The Dark Mind" lc="0"></station>
|
46
|
+
<station name="Chicago Metalworks Radio - Chicago's Only True Metal Station! Playing Non-Stop Metal/Death & Rock 2" mt="audio/mpeg" id="522807" br="128" genre="Metal Death Hard Rock" ct="Chevelle - Another Know It All" lc="0"></station>
|
47
|
+
<station name="GotRadio - Alternative" mt="audio/mpeg" id="553888" br="32" genre="Alternative Alternative " ct="Death Cab For Cutie - I Will Possess Your Heart (edit)" lc="0"></station>
|
48
|
+
<station name="ACiDMETALFM" mt="audio/mpeg" id="582096" br="128" genre="Death Metal Hard Core" ct="Haunted - No Compromise" lc="0"></station>
|
49
|
+
<station name="Radio13 - http://ochakovo.2cd.net" mt="audio/mpeg" id="642440" br="128" genre="Metal Thrash Death " ct="Deadly Blessing - Silent Madness" lc="0"></station>
|
50
|
+
<station name="Chicago Metalworks Radio - Chicago's Only True Metal Station! Playing Non-Stop Metal/Death & Rock 2" mt="audio/mpeg" id="661129" br="64" genre="Metal Death Hard Rock" ct="Foo Fighters - Hey, Johnny Park!" lc="0"></station>
|
51
|
+
<station name="Wolf Lair Radio WOLFLAIRRADIO NSBM Black Metal Death Metal Pagan Metal Elegy" mt="audio/mpeg" id="740853" br="48" genre="NSBM Death metal Black Me" ct="Impending Doom - Armageddon Tales" lc="0"></station>
|
52
|
+
<station name="Death" mt="audio/mpeg" id="769809" br="24" genre="Death" ct="Izel - Izel - Kiyamadim" lc="0"></station>
|
53
|
+
</stationlist>
|
data/test/helper.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), "..", "lib")
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'test/unit'
|
5
|
+
require 'mocha'
|
6
|
+
|
7
|
+
require 'shoutcast_api'
|
8
|
+
|
9
|
+
module TestExtensions
|
10
|
+
def file_fixture(filename)
|
11
|
+
File.read(File.join(File.dirname(__FILE__), 'fixtures', filename.to_s))
|
12
|
+
end
|
13
|
+
|
14
|
+
def stub_http_response_with(filename)
|
15
|
+
format = filename.split('.').last.intern
|
16
|
+
data = file_fixture(filename)
|
17
|
+
|
18
|
+
response = Net::HTTPOK.new("1.1", 200, "Content for you")
|
19
|
+
response.stubs(:body).returns(data)
|
20
|
+
|
21
|
+
http_request = HTTParty::Request.new(Net::HTTP::Get, 'http://localhost', :format => format)
|
22
|
+
http_request.stubs(:perform_actual_request).returns(response)
|
23
|
+
|
24
|
+
HTTParty::Request.expects(:new).returns(http_request)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
Test::Unit::TestCase.send(:include, TestExtensions)
|
data/test/test_basic.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'helper')
|
2
|
+
|
3
|
+
class ShoutcastTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def test_delegators
|
6
|
+
assert_respond_to Shoutcast, :genres
|
7
|
+
assert_respond_to Shoutcast, :search
|
8
|
+
end
|
9
|
+
|
10
|
+
end
|
11
|
+
|
12
|
+
class ExtensionsTest < Test::Unit::TestCase
|
13
|
+
|
14
|
+
def test_file_fixture
|
15
|
+
assert_equal "", file_fixture("empty.plain")
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_http_response_stubbing
|
19
|
+
stub_http_response_with("empty.plain")
|
20
|
+
|
21
|
+
assert_equal "", HTTParty.get('').body
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'helper')
|
2
|
+
|
3
|
+
class FetcherTest < Test::Unit::TestCase
|
4
|
+
include Shoutcast
|
5
|
+
|
6
|
+
def test_base_uri
|
7
|
+
assert_equal "http://yp.shoutcast.com", Stationlist.base_uri
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_genres_list
|
11
|
+
stub_http_response_with("genrelist.plain")
|
12
|
+
|
13
|
+
list = Fetcher.genres
|
14
|
+
# DRY test/text_xml.rb GenrelistTest
|
15
|
+
assert_instance_of Genrelist, list
|
16
|
+
assert_instance_of Genre, list.first
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_genres_empty_response
|
20
|
+
stub_http_response_with("empty.plain")
|
21
|
+
|
22
|
+
assert_nil Fetcher.genres
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_search_with_invalid_option
|
26
|
+
stub_http_response_with("search_death.plain")
|
27
|
+
|
28
|
+
list = Fetcher.search
|
29
|
+
# DRY test/text_xml.rb StationlistTest
|
30
|
+
assert_instance_of Stationlist, list
|
31
|
+
assert_equal "/sbin/tunein-station.pls", list.tunein_base_path
|
32
|
+
assert_instance_of Station, list.first
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_search_empty_response
|
36
|
+
stub_http_response_with("empty.plain")
|
37
|
+
|
38
|
+
assert_nil Fetcher.genres
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
data/test/test_xml.rb
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'helper')
|
2
|
+
|
3
|
+
class StationTest < Test::Unit::TestCase
|
4
|
+
include Shoutcast
|
5
|
+
|
6
|
+
def setup
|
7
|
+
xml = <<-XML
|
8
|
+
<station
|
9
|
+
id="1234"
|
10
|
+
name=" Metal radio "
|
11
|
+
mt="audio/mpeg"
|
12
|
+
br="128"
|
13
|
+
genre=" Metal Rock "
|
14
|
+
ct=" Heavy Metal Band "
|
15
|
+
lc="123"/>
|
16
|
+
XML
|
17
|
+
|
18
|
+
@station = Station.from_xml xml
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_parsing
|
22
|
+
assert_instance_of Station, @station
|
23
|
+
assert_equal 1234, @station.id
|
24
|
+
assert_equal "Metal radio", @station.name
|
25
|
+
assert_equal "audio/mpeg", @station.media_type
|
26
|
+
assert_equal 128, @station.bitrate
|
27
|
+
assert_equal "Metal Rock", @station.genre
|
28
|
+
assert_equal "Heavy Metal Band", @station.current_title
|
29
|
+
assert_equal 123, @station.listeners
|
30
|
+
assert_nil @station.tunein
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_type
|
34
|
+
assert_equal "mpeg", @station.type
|
35
|
+
|
36
|
+
def @station.media_type
|
37
|
+
"strange format"
|
38
|
+
end
|
39
|
+
|
40
|
+
assert_equal "strange format", @station.type
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_to_s
|
44
|
+
string = @station.to_s
|
45
|
+
|
46
|
+
assert string.include?(@station.id.to_s)
|
47
|
+
assert string.include?(@station.name)
|
48
|
+
assert string.include?(@station.current_title)
|
49
|
+
assert string.include?(@station.bitrate.to_s)
|
50
|
+
assert string.include?(@station.listeners.to_s)
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_header
|
54
|
+
string = Station.header
|
55
|
+
|
56
|
+
assert string.include?("id")
|
57
|
+
assert string.include?("station-name")
|
58
|
+
assert string.include?("title")
|
59
|
+
assert string.include?("bit")
|
60
|
+
assert string.include?("listen.")
|
61
|
+
end
|
62
|
+
|
63
|
+
# TODO test <=>
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
class StationlistTest < Test::Unit::TestCase
|
69
|
+
include Shoutcast
|
70
|
+
|
71
|
+
def setup
|
72
|
+
@list = Stationlist.from_xml file_fixture("search_death.plain")
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_attributes
|
76
|
+
assert_instance_of Stationlist, @list
|
77
|
+
assert_equal "/sbin/tunein-station.pls", @list.tunein_base_path
|
78
|
+
assert_equal 49, @list.size
|
79
|
+
assert_instance_of Station, @list.first
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_base_uri
|
83
|
+
assert_equal "http://yp.shoutcast.com", Stationlist.base_uri
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_tunein
|
87
|
+
station = @list.first
|
88
|
+
|
89
|
+
assert_equal "http://yp.shoutcast.com/sbin/tunein-station.pls?id=#{station.id}", @list.tunein(station)
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_tunein_propagtion_after_parse
|
93
|
+
station = @list.first
|
94
|
+
|
95
|
+
assert_equal @list.tunein(station), station.tunein
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
class GenrelistTest < Test::Unit::TestCase
|
102
|
+
include Shoutcast
|
103
|
+
|
104
|
+
def setup
|
105
|
+
@list = Genrelist.from_xml file_fixture("genrelist.plain")
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_array_mimic
|
109
|
+
assert_instance_of Genrelist, @list
|
110
|
+
assert_equal 434, @list.size
|
111
|
+
assert_instance_of Genre, @list.first
|
112
|
+
assert_respond_to @list, :each
|
113
|
+
assert_raise(NoMethodError) { @list.nothing_found }
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_genre_name
|
117
|
+
sorted = @list.sort
|
118
|
+
|
119
|
+
assert_equal "24h", sorted.first.name
|
120
|
+
assert_equal "Zouk", sorted.last.name
|
121
|
+
end
|
122
|
+
|
123
|
+
def test_genre_to_s
|
124
|
+
genre = @list.first
|
125
|
+
|
126
|
+
assert_equal genre.name, genre.to_s
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
|
131
|
+
|
132
|
+
class MyClass
|
133
|
+
include Shoutcast::Xml
|
134
|
+
end
|
135
|
+
|
136
|
+
class XmlTest < Test::Unit::TestCase
|
137
|
+
|
138
|
+
def test_trim
|
139
|
+
assert_respond_to MyClass, :trim
|
140
|
+
|
141
|
+
string = " test mee "
|
142
|
+
assert_equal "test mee", MyClass.trim.call(string)
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
metadata
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: shoutcast_api
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Peter Suschlik
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-05-14 00:00:00 +02:00
|
13
|
+
default_executable: shoutcast_search
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: httparty
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ~>
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0.4"
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: roxml
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "2.5"
|
34
|
+
version:
|
35
|
+
description: Simple Shoutcast.com API.
|
36
|
+
email: peter-scapi@suschlik.de
|
37
|
+
executables:
|
38
|
+
- shoutcast_search
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files:
|
42
|
+
- bin/shoutcast_search
|
43
|
+
- lib/shoutcast_api.rb
|
44
|
+
- README.rdoc
|
45
|
+
files:
|
46
|
+
- Rakefile
|
47
|
+
- bin/shoutcast_search
|
48
|
+
- lib/shoutcast_api.rb
|
49
|
+
- README.rdoc
|
50
|
+
- Manifest
|
51
|
+
- test/test_xml.rb
|
52
|
+
- test/helper.rb
|
53
|
+
- test/test_fetcher.rb
|
54
|
+
- test/fixtures/genrelist.plain
|
55
|
+
- test/fixtures/search_death.plain
|
56
|
+
- test/fixtures/empty.plain
|
57
|
+
- test/test_basic.rb
|
58
|
+
- shoutcast_api.gemspec
|
59
|
+
has_rdoc: true
|
60
|
+
homepage: http://github.com/splattael/shoutcast_api
|
61
|
+
licenses: []
|
62
|
+
|
63
|
+
post_install_message:
|
64
|
+
rdoc_options:
|
65
|
+
- --line-numbers
|
66
|
+
- --inline-source
|
67
|
+
- --title
|
68
|
+
- Shoutcast_api
|
69
|
+
- --main
|
70
|
+
- README.rdoc
|
71
|
+
require_paths:
|
72
|
+
- lib
|
73
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: "0"
|
78
|
+
version:
|
79
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: "1.2"
|
84
|
+
version:
|
85
|
+
requirements: []
|
86
|
+
|
87
|
+
rubyforge_project: shoutcast_api
|
88
|
+
rubygems_version: 1.3.5
|
89
|
+
signing_key:
|
90
|
+
specification_version: 2
|
91
|
+
summary: Ruby API for Shoutcast.com.
|
92
|
+
test_files:
|
93
|
+
- test/test_xml.rb
|
94
|
+
- test/test_fetcher.rb
|
95
|
+
- test/test_basic.rb
|