bremen 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Guardfile +0 -1
- data/README.md +55 -2
- data/bremen.gemspec +3 -2
- data/lib/bremen/base.rb +9 -3
- data/lib/bremen/mixcloud.rb +15 -3
- data/lib/bremen/nicovideo.rb +27 -4
- data/lib/bremen/soundcloud.rb +20 -5
- data/lib/bremen/version.rb +1 -1
- data/lib/bremen/youtube.rb +14 -2
- data/spec/bremen/mixcloud_spec.rb +28 -3
- data/spec/bremen/nicovideo_spec.rb +28 -3
- data/spec/bremen/soundcloud_spec.rb +50 -15
- data/spec/bremen/youtube_spec.rb +28 -3
- data/spec/fixtures/{mixcloud.json → mixcloud_multi.json} +0 -0
- data/spec/fixtures/mixcloud_single.json +43 -0
- data/spec/fixtures/{nicovideo.html → nicovideo_multi.html} +0 -0
- data/spec/fixtures/nicovideo_single.html +91 -0
- data/spec/fixtures/{soundcloud.json → soundcloud_multi.json} +0 -0
- data/spec/fixtures/soundcloud_single.json +53 -0
- data/spec/fixtures/{youtube.json → youtube_multi.json} +0 -0
- data/spec/fixtures/youtube_single.json +262 -0
- data/spec/spec_helper.rb +1 -0
- metadata +37 -12
data/Guardfile
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Bremen
|
2
2
|
|
3
|
-
|
3
|
+
**Bremen** provides common search interface for some music websites. it supports YouTube, SoundCloud, MixCloud and Nicovideo
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
@@ -16,9 +16,62 @@ Or install it yourself as:
|
|
16
16
|
|
17
17
|
$ gem install bremen
|
18
18
|
|
19
|
+
## Setting
|
20
|
+
|
21
|
+
As far as Soundcloud concerned, you need to set consumer key before using.
|
22
|
+
|
23
|
+
Bremen::Soundcloud.consumer_key = 'your_consumer_key'
|
24
|
+
|
19
25
|
## Usage
|
20
26
|
|
21
|
-
|
27
|
+
### Retrieving a single track
|
28
|
+
|
29
|
+
call `.find` method with uid(unique key) or url.
|
30
|
+
|
31
|
+
Bremen::Youtube.find('XXXXXXXXXXX')
|
32
|
+
Bremen::Youtube.find('http://www.youtube.com/watch?v=XXXXXXXXXXX')
|
33
|
+
Bremen::Soundcloud.find('1111111')
|
34
|
+
Bremen::Soundcloud.find('http://soundcloud.com/author/title')
|
35
|
+
Bremen::Mixcloud.find('/author/title/')
|
36
|
+
Bremen::Mixcloud.find('http://www.mixcloud.com/author/title/')
|
37
|
+
Bremen::Nicovideo.find('sm1111111')
|
38
|
+
Bremen::Nicovideo.find('http://www.nicovideo.jp/watch/sm1111111')
|
39
|
+
|
40
|
+
### Retrieving multiple tracks
|
41
|
+
|
42
|
+
call `.search` method with keyword.
|
43
|
+
|
44
|
+
Bremen::Youtube.find(keyword: 'Perfume')
|
45
|
+
|
46
|
+
#### Optional params
|
47
|
+
|
48
|
+
You can add optional parameters for filtering. But not supports all official API's filters.
|
49
|
+
|
50
|
+
Bremen::Youtube.find(keyword: 'KyaryPamyuPamyu', order: 'relevance', limit: 10)
|
51
|
+
|
52
|
+
### Track object
|
53
|
+
|
54
|
+
Retrieving methods return Track object(s).
|
55
|
+
|
56
|
+
attribute | |
|
57
|
+
-----------|----------------------|
|
58
|
+
uid | unique key in a site |
|
59
|
+
url | |
|
60
|
+
title | |
|
61
|
+
author | |
|
62
|
+
length | duration of track |
|
63
|
+
created_at | released datetime |
|
64
|
+
updated_at | modified datetime |
|
65
|
+
|
66
|
+
## API References
|
67
|
+
|
68
|
+
- [Reference Guide: Data API Protocol - YouTube — Google Developers](https://developers.google.com/youtube/2.0/reference#Searching_for_videos)
|
69
|
+
- [Docs - API - Reference - SoundCloud Developers](http://developers.soundcloud.com/docs/api/reference#tracks)
|
70
|
+
- [API documentation | Mixcloud](http://www.mixcloud.com/developers/documentation/#search)
|
71
|
+
|
72
|
+
## Supported versions
|
73
|
+
|
74
|
+
- Ruby 1.9.3 or higher
|
22
75
|
|
23
76
|
## Contributing
|
24
77
|
|
data/bremen.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |gem|
|
|
8
8
|
gem.version = Bremen::VERSION
|
9
9
|
gem.authors = ["itzki"]
|
10
10
|
gem.email = ["itzki.h@gmail.com"]
|
11
|
-
gem.description = %q{integrated searcher of audio
|
12
|
-
gem.summary = %q{
|
11
|
+
gem.description = %q{integrated searcher of audio tracks on music sites}
|
12
|
+
gem.summary = %q{Bremen provides common search interface for some music websites. it supports YouTube, SoundCloud, MixCloud and Nicovideo}
|
13
13
|
gem.homepage = "https://github.com/itzki/bremen"
|
14
14
|
|
15
15
|
gem.files = `git ls-files`.split($/)
|
@@ -19,4 +19,5 @@ Gem::Specification.new do |gem|
|
|
19
19
|
|
20
20
|
gem.add_development_dependency 'guard-minitest', ['>= 0']
|
21
21
|
gem.add_development_dependency 'rb-fsevent', ['>= 0']
|
22
|
+
gem.add_development_dependency 'terminal-notifier-guard', ['>= 0']
|
22
23
|
end
|
data/lib/bremen/base.rb
CHANGED
@@ -9,14 +9,20 @@ module Bremen
|
|
9
9
|
class << self
|
10
10
|
attr_accessor :default_options
|
11
11
|
|
12
|
-
def find
|
13
|
-
|
12
|
+
def find uid_or_url
|
13
|
+
convert_singly(get(find_url(uid_or_url)))
|
14
|
+
end
|
15
|
+
|
16
|
+
def search options = {}
|
17
|
+
convert_multiply(get(search_url(options)))
|
14
18
|
end
|
15
19
|
|
16
20
|
#abstract methods
|
21
|
+
def find_url uid_or_url; end
|
17
22
|
def search_url options = {}; end
|
18
23
|
private
|
19
|
-
def
|
24
|
+
def convert_singly response; end
|
25
|
+
def convert_multiply response; end
|
20
26
|
end
|
21
27
|
end
|
22
28
|
end
|
data/lib/bremen/mixcloud.rb
CHANGED
@@ -3,13 +3,21 @@ require 'bremen/base'
|
|
3
3
|
|
4
4
|
module Bremen
|
5
5
|
class Mixcloud < Bremen::Base
|
6
|
-
BASE_URL = 'http://api.mixcloud.com/
|
6
|
+
BASE_URL = 'http://api.mixcloud.com/'
|
7
7
|
self.default_options = {
|
8
8
|
keyword: '',
|
9
9
|
limit: 20,
|
10
10
|
}
|
11
11
|
|
12
12
|
class << self
|
13
|
+
def find_url uid_or_url
|
14
|
+
if uid_or_url.to_s.include?('www.mixcloud.com')
|
15
|
+
uid_or_url.sub('www.mixcloud.com', 'api.mixcloud.com')
|
16
|
+
else
|
17
|
+
"#{BASE_URL[0..-2]}#{uid_or_url}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
13
21
|
def search_url options = {}
|
14
22
|
options = default_options.merge(options)
|
15
23
|
query = {
|
@@ -17,7 +25,7 @@ module Bremen
|
|
17
25
|
limit: options[:limit],
|
18
26
|
type: 'cloudcast',
|
19
27
|
}
|
20
|
-
"#{BASE_URL}
|
28
|
+
"#{BASE_URL}search/?#{build_query(query)}"
|
21
29
|
end
|
22
30
|
|
23
31
|
def from_api hash = {}
|
@@ -34,7 +42,11 @@ module Bremen
|
|
34
42
|
end
|
35
43
|
|
36
44
|
private
|
37
|
-
def
|
45
|
+
def convert_singly response
|
46
|
+
from_api(JSON.parse(response))
|
47
|
+
end
|
48
|
+
|
49
|
+
def convert_multiply response
|
38
50
|
JSON.parse(response)['data'].map{|t| from_api(t) }
|
39
51
|
end
|
40
52
|
end
|
data/lib/bremen/nicovideo.rb
CHANGED
@@ -3,7 +3,7 @@ require 'bremen/base'
|
|
3
3
|
|
4
4
|
module Bremen
|
5
5
|
class Nicovideo < Bremen::Base
|
6
|
-
BASE_URL = 'http://www.nicovideo.jp/
|
6
|
+
BASE_URL = 'http://www.nicovideo.jp/'
|
7
7
|
self.default_options = {
|
8
8
|
keyword: '',
|
9
9
|
sort: 'f', #n(newer commented)/v(viewed)/r(most commented)/m(listed)/f(uploaded)/l(duration)
|
@@ -14,6 +14,14 @@ module Bremen
|
|
14
14
|
}
|
15
15
|
|
16
16
|
class << self
|
17
|
+
def find_url uid_or_url
|
18
|
+
unless uid_or_url.include?('www.nicovideo.jp')
|
19
|
+
"#{BASE_URL}watch/#{uid_or_url}"
|
20
|
+
else
|
21
|
+
uid_or_url
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
17
25
|
def search_url options = {}
|
18
26
|
options = default_options.merge(options)
|
19
27
|
query = {
|
@@ -23,18 +31,33 @@ module Bremen
|
|
23
31
|
l_range: options[:length],
|
24
32
|
opt_md: options[:downloadable],
|
25
33
|
}
|
26
|
-
"#{BASE_URL}
|
34
|
+
"#{BASE_URL}search/#{CGI.escape(options[:keyword])}?#{build_query(query)}"
|
27
35
|
end
|
28
36
|
|
29
37
|
private
|
30
|
-
def
|
38
|
+
def convert_singly response
|
39
|
+
uid = response.scan(%r{<link rel="canonical" href="/watch/([^"]+)">}).flatten.first
|
40
|
+
title = CGI.unescape(response.scan(%r{<meta property="og:title" content="(.+)">}).flatten.first.to_s)
|
41
|
+
length = response.scan(%r{<meta property="video:duration" content="(\d+)">}).flatten.first.to_i
|
42
|
+
created_at = Time.parse(response.scan(%r{<meta property="video:release_date" content="(.+)">}).flatten.first.to_s)
|
43
|
+
new({
|
44
|
+
uid: uid,
|
45
|
+
url: "#{BASE_URL}watch/#{uid}",
|
46
|
+
title: title,
|
47
|
+
length: length,
|
48
|
+
created_at: created_at,
|
49
|
+
updated_at: created_at,
|
50
|
+
})
|
51
|
+
end
|
52
|
+
|
53
|
+
def convert_multiply response
|
31
54
|
response.scan(%r{<div class="thumb_col_1">\n<!---->\n(.*?)\n<!---->\n</div></div>}m).flatten.map do |html|
|
32
55
|
uid = html.scan(%r{<table [^>]+ summary="(.+)">}).flatten.first
|
33
56
|
min, sec = html.scan(%r{<p class="vinfo_length"><span>([\d:]+)</span></p>}).flatten.first.to_s.split(':')
|
34
57
|
created_at = Time.parse(html.scan(%r{<strong>(.+:\d\d)</strong>}).flatten.first.to_s.gsub(/\xE5\xB9\xB4|\xE6\x9C\x88|\xE6\x97\xA5/, ''))
|
35
58
|
new({
|
36
59
|
uid: uid,
|
37
|
-
url: "
|
60
|
+
url: "#{BASE_URL}watch/#{uid}",
|
38
61
|
title: CGI.unescape(html.scan(%r{<a [^>]+ class="watch" [^>]+>(.+)</a>}).flatten.first.to_s),
|
39
62
|
length: min.to_i * 60 + sec.to_i,
|
40
63
|
created_at: created_at,
|
data/lib/bremen/soundcloud.rb
CHANGED
@@ -3,7 +3,7 @@ require 'bremen/base'
|
|
3
3
|
|
4
4
|
module Bremen
|
5
5
|
class Soundcloud < Bremen::Base
|
6
|
-
BASE_URL = 'http://api.soundcloud.com/
|
6
|
+
BASE_URL = 'http://api.soundcloud.com/'
|
7
7
|
self.default_options = {
|
8
8
|
keyword: '',
|
9
9
|
order: 'created_at', #created_at/hotness
|
@@ -14,17 +14,28 @@ module Bremen
|
|
14
14
|
class << self
|
15
15
|
attr_accessor :consumer_key
|
16
16
|
|
17
|
-
def
|
17
|
+
def build_query options = {}
|
18
18
|
raise %Q{"#{self.name}.consumer_key" must be set} unless consumer_key
|
19
|
+
super(options.merge(consumer_key: consumer_key))
|
20
|
+
end
|
21
|
+
|
22
|
+
def find_url uid_or_url
|
23
|
+
if uid_or_url.to_s =~ %r{\A\d+\Z}
|
24
|
+
"#{BASE_URL}tracks/#{uid_or_url}.json?#{build_query}"
|
25
|
+
else
|
26
|
+
"#{BASE_URL}resolve.json?#{build_query({url: uid_or_url})}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def search_url options = {}
|
19
31
|
options = default_options.merge(options)
|
20
32
|
query = {
|
21
33
|
q: options[:keyword],
|
22
34
|
order: options[:order],
|
23
35
|
limit: options[:limit],
|
24
36
|
filter: options[:filter],
|
25
|
-
consumer_key: consumer_key,
|
26
37
|
}
|
27
|
-
"#{BASE_URL}?#{build_query(query)}"
|
38
|
+
"#{BASE_URL}tracks.json?#{build_query(query)}"
|
28
39
|
end
|
29
40
|
|
30
41
|
def from_api hash = {}
|
@@ -40,7 +51,11 @@ module Bremen
|
|
40
51
|
end
|
41
52
|
|
42
53
|
private
|
43
|
-
def
|
54
|
+
def convert_singly response
|
55
|
+
from_api(JSON.parse(response))
|
56
|
+
end
|
57
|
+
|
58
|
+
def convert_multiply response
|
44
59
|
JSON.parse(response).map{|t| from_api(t) }
|
45
60
|
end
|
46
61
|
end
|
data/lib/bremen/version.rb
CHANGED
data/lib/bremen/youtube.rb
CHANGED
@@ -12,13 +12,21 @@ module Bremen
|
|
12
12
|
}
|
13
13
|
|
14
14
|
class << self
|
15
|
+
def build_query options = {}
|
16
|
+
super(options.merge(alt: 'json'))
|
17
|
+
end
|
18
|
+
|
19
|
+
def find_url uid_or_url
|
20
|
+
uid = uid_or_url.scan(%r{[?&]v=(.{11})}).flatten.first || uid_or_url
|
21
|
+
"#{BASE_URL}#{uid}?#{build_query}"
|
22
|
+
end
|
23
|
+
|
15
24
|
def search_url options = {}
|
16
25
|
options = default_options.merge(options)
|
17
26
|
query = {
|
18
27
|
vq: options[:keyword],
|
19
28
|
orderby: options[:order],
|
20
29
|
:"max-results" => options[:limit],
|
21
|
-
alt: 'json',
|
22
30
|
}
|
23
31
|
"#{BASE_URL}-/#{options[:category]}/#{options[:tag]}/?#{build_query(query)}"
|
24
32
|
end
|
@@ -37,7 +45,11 @@ module Bremen
|
|
37
45
|
end
|
38
46
|
|
39
47
|
private
|
40
|
-
def
|
48
|
+
def convert_singly response
|
49
|
+
from_api(JSON.parse(response)['entry'])
|
50
|
+
end
|
51
|
+
|
52
|
+
def convert_multiply response
|
41
53
|
JSON.parse(response)['feed']['entry'].map{|t| from_api(t) }
|
42
54
|
end
|
43
55
|
end
|
@@ -2,6 +2,23 @@ $:.unshift(File.expand_path('../../', __FILE__))
|
|
2
2
|
require 'spec_helper'
|
3
3
|
|
4
4
|
describe Bremen::Mixcloud do
|
5
|
+
describe '.find_url' do
|
6
|
+
subject{ Bremen::Mixcloud.find_url(uid_or_url) }
|
7
|
+
describe 'given id' do
|
8
|
+
let(:uid_or_url){ '/author/permalink/' }
|
9
|
+
it 'generate' do
|
10
|
+
subject.must_equal 'http://api.mixcloud.com/author/permalink/'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe 'given url' do
|
15
|
+
let(:uid_or_url){ 'http://www.mixcloud.com/author/permalink/' }
|
16
|
+
it 'generate' do
|
17
|
+
subject.must_equal 'http://api.mixcloud.com/author/permalink/'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
5
22
|
describe '.search_url' do
|
6
23
|
subject{ Bremen::Mixcloud.search_url(params) }
|
7
24
|
describe 'only keyword' do
|
@@ -19,9 +36,17 @@ describe Bremen::Mixcloud do
|
|
19
36
|
end
|
20
37
|
end
|
21
38
|
|
22
|
-
describe '.
|
23
|
-
subject{ Bremen::Mixcloud.send(:
|
24
|
-
let(:response){ fixture('
|
39
|
+
describe '.convert_singly' do
|
40
|
+
subject{ Bremen::Mixcloud.send(:convert_singly, response) }
|
41
|
+
let(:response){ fixture('mixcloud_single.json') }
|
42
|
+
it 'convert successfully' do
|
43
|
+
subject.title.must_equal 'Title'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '.convert_multiply' do
|
48
|
+
subject{ Bremen::Mixcloud.send(:convert_multiply, response) }
|
49
|
+
let(:response){ fixture('mixcloud_multi.json') }
|
25
50
|
it 'convert successfully' do
|
26
51
|
subject.first.title.must_equal 'Title'
|
27
52
|
end
|
@@ -2,6 +2,23 @@ $:.unshift(File.expand_path('../../', __FILE__))
|
|
2
2
|
require 'spec_helper'
|
3
3
|
|
4
4
|
describe Bremen::Nicovideo do
|
5
|
+
describe '.find_url' do
|
6
|
+
subject{ Bremen::Nicovideo.find_url(uid_or_url) }
|
7
|
+
describe 'given id' do
|
8
|
+
let(:uid_or_url){ 'sm1111111' }
|
9
|
+
it 'generate' do
|
10
|
+
subject.must_equal 'http://www.nicovideo.jp/watch/sm1111111'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe 'given url' do
|
15
|
+
let(:uid_or_url){ 'http://www.nicovideo.jp/watch/sm1111111' }
|
16
|
+
it 'generate' do
|
17
|
+
subject.must_equal 'http://www.nicovideo.jp/watch/sm1111111'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
5
22
|
describe '.search_url' do
|
6
23
|
subject{ Bremen::Nicovideo.search_url(params) }
|
7
24
|
describe 'only keyword' do
|
@@ -19,9 +36,17 @@ describe Bremen::Nicovideo do
|
|
19
36
|
end
|
20
37
|
end
|
21
38
|
|
22
|
-
describe '.
|
23
|
-
subject{ Bremen::Nicovideo.send(:
|
24
|
-
let(:response){ fixture('
|
39
|
+
describe '.convert_singly' do
|
40
|
+
subject{ Bremen::Nicovideo.send(:convert_singly, response) }
|
41
|
+
let(:response){ fixture('nicovideo_single.html') }
|
42
|
+
it 'convert successfully' do
|
43
|
+
subject.title.must_equal 'Title'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '.convert_multiply' do
|
48
|
+
subject{ Bremen::Nicovideo.send(:convert_multiply, response) }
|
49
|
+
let(:response){ fixture('nicovideo_multi.html') }
|
25
50
|
it 'convert successfully' do
|
26
51
|
subject.first.title.must_equal 'Title'
|
27
52
|
end
|
@@ -2,34 +2,69 @@ $:.unshift(File.expand_path('../../', __FILE__))
|
|
2
2
|
require 'spec_helper'
|
3
3
|
|
4
4
|
describe Bremen::Soundcloud do
|
5
|
-
describe '.
|
5
|
+
describe '.build_query' do
|
6
6
|
describe 'not set consumer_key' do
|
7
7
|
it 'raise error' do
|
8
8
|
lambda{ Bremen::Soundcloud.search_url }.must_raise RuntimeError
|
9
9
|
end
|
10
10
|
end
|
11
|
+
|
11
12
|
describe 'set consumer_key' do
|
12
13
|
before{ Bremen::Soundcloud.consumer_key = 'CK' }
|
13
|
-
subject{ Bremen::Soundcloud.
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
subject{ Bremen::Soundcloud.build_query({a: 'b'}) }
|
15
|
+
it 'return query string' do
|
16
|
+
subject.must_equal 'a=b&consumer_key=CK'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '.find_url' do
|
22
|
+
before{ Bremen::Soundcloud.consumer_key = 'CK' }
|
23
|
+
subject{ Bremen::Soundcloud.find_url(uid_or_url) }
|
24
|
+
describe 'given id' do
|
25
|
+
let(:uid_or_url){ 100 }
|
26
|
+
it 'generate directly' do
|
27
|
+
subject.must_equal 'http://api.soundcloud.com/tracks/100.json?consumer_key=CK'
|
19
28
|
end
|
29
|
+
end
|
20
30
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
end
|
31
|
+
describe 'given url' do
|
32
|
+
let(:uid_or_url){ 'http://soundcloud.com/author/permalink' }
|
33
|
+
it 'generate with resolve resource' do
|
34
|
+
subject.must_equal 'http://api.soundcloud.com/resolve.json?url=http%3A%2F%2Fsoundcloud.com%2Fauthor%2Fpermalink&consumer_key=CK'
|
26
35
|
end
|
27
36
|
end
|
28
37
|
end
|
29
38
|
|
30
|
-
describe '.
|
31
|
-
|
32
|
-
|
39
|
+
describe '.search_url' do
|
40
|
+
before{ Bremen::Soundcloud.consumer_key = 'CK' }
|
41
|
+
subject{ Bremen::Soundcloud.search_url(params) }
|
42
|
+
describe 'only keyword' do
|
43
|
+
let(:params){ {keyword: 'searchword'} }
|
44
|
+
it 'generate' do
|
45
|
+
subject.must_equal 'http://api.soundcloud.com/tracks.json?q=searchword&order=created_at&limit=50&filter=&consumer_key=CK'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe 'full params' do
|
50
|
+
let(:params){ {keyword: 'searchword', order: 'hotness', limit: 1, filter: 'public'} }
|
51
|
+
it 'generate' do
|
52
|
+
subject.must_equal 'http://api.soundcloud.com/tracks.json?q=searchword&order=hotness&limit=1&filter=public&consumer_key=CK'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe '.convert_singly' do
|
58
|
+
subject{ Bremen::Soundcloud.send(:convert_singly, response) }
|
59
|
+
let(:response){ fixture('soundcloud_single.json') }
|
60
|
+
it 'convert successfully' do
|
61
|
+
subject.title.must_equal 'Title'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe '.convert_multiply' do
|
66
|
+
subject{ Bremen::Soundcloud.send(:convert_multiply, response) }
|
67
|
+
let(:response){ fixture('soundcloud_multi.json') }
|
33
68
|
it 'convert successfully' do
|
34
69
|
subject.first.title.must_equal 'Title'
|
35
70
|
end
|
data/spec/bremen/youtube_spec.rb
CHANGED
@@ -2,6 +2,23 @@ $:.unshift(File.expand_path('../../', __FILE__))
|
|
2
2
|
require 'spec_helper'
|
3
3
|
|
4
4
|
describe Bremen::Youtube do
|
5
|
+
describe '.find_url' do
|
6
|
+
subject{ Bremen::Youtube.find_url(uid_or_url) }
|
7
|
+
describe 'given id' do
|
8
|
+
let(:uid_or_url){ 'XXXXXXXXXXX' }
|
9
|
+
it 'generate' do
|
10
|
+
subject.must_equal 'http://gdata.youtube.com/feeds/api/videos/XXXXXXXXXXX?alt=json'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe 'given url' do
|
15
|
+
let(:uid_or_url){ 'http://www.youtube.com/watch?v=XXXXXXXXXXX' }
|
16
|
+
it 'generate' do
|
17
|
+
subject.must_equal 'http://gdata.youtube.com/feeds/api/videos/XXXXXXXXXXX?alt=json'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
5
22
|
describe '.search_url' do
|
6
23
|
subject{ Bremen::Youtube.search_url(params) }
|
7
24
|
describe 'only keyword' do
|
@@ -19,9 +36,17 @@ describe Bremen::Youtube do
|
|
19
36
|
end
|
20
37
|
end
|
21
38
|
|
22
|
-
describe '.
|
23
|
-
subject{ Bremen::Youtube.send(:
|
24
|
-
let(:response){ fixture('
|
39
|
+
describe '.convert_singly' do
|
40
|
+
subject{ Bremen::Youtube.send(:convert_singly, response) }
|
41
|
+
let(:response){ fixture('youtube_single.json') }
|
42
|
+
it 'convert successfully' do
|
43
|
+
subject.title.must_equal 'Title'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '.convert_multiply' do
|
48
|
+
subject{ Bremen::Youtube.send(:convert_multiply, response) }
|
49
|
+
let(:response){ fixture('youtube_multi.json') }
|
25
50
|
it 'convert successfully' do
|
26
51
|
subject.first.title.must_equal 'Title'
|
27
52
|
end
|
File without changes
|
@@ -0,0 +1,43 @@
|
|
1
|
+
{
|
2
|
+
"listener_count": 111,
|
3
|
+
"name": "Title",
|
4
|
+
"tags": [
|
5
|
+
{
|
6
|
+
"url": "http://www.mixcloud.com/tag/tag1/",
|
7
|
+
"name": "Inna",
|
8
|
+
"key": "/tag/tag1/"
|
9
|
+
}
|
10
|
+
],
|
11
|
+
"url": "http://www.mixcloud.com/author/title/",
|
12
|
+
"pictures": {
|
13
|
+
"medium": "http://images-mix.netdna-ssl.com/w/100/h/100/q/85/upload/images/extaudio/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.png",
|
14
|
+
"extra_large": "http://images-mix.netdna-ssl.com/w/600/h/600/q/85/upload/images/extaudio/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.png",
|
15
|
+
"large": "http://images-mix.netdna-ssl.com/w/300/h/300/q/85/upload/images/extaudio/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.png",
|
16
|
+
"medium_mobile": "http://images-mix.netdna-ssl.com/w/80/h/80/q/75/upload/images/extaudio/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.png",
|
17
|
+
"small": "http://images-mix.netdna-ssl.com/w/25/h/25/q/85/upload/images/extaudio/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.png",
|
18
|
+
"thumbnail": "http://images-mix.netdna-ssl.com/w/50/h/50/q/85/upload/images/extaudio/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.png"
|
19
|
+
},
|
20
|
+
"updated_time": "2012-01-01T00:00:00Z",
|
21
|
+
"play_count": 1111,
|
22
|
+
"comment_count": 1,
|
23
|
+
"percentage_music": 100,
|
24
|
+
"user": {
|
25
|
+
"url": "http://www.mixcloud.com/author/",
|
26
|
+
"username": "author",
|
27
|
+
"name": "Author",
|
28
|
+
"key": "/author/",
|
29
|
+
"pictures": {
|
30
|
+
"medium": "http://images-mix.netdna-ssl.com/w/100/h/100/q/85/upload/images/profile/xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx.png",
|
31
|
+
"extra_large": "http://images-mix.netdna-ssl.com/w/600/h/600/q/85/upload/images/profile/xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx.png",
|
32
|
+
"large": "http://images-mix.netdna-ssl.com/w/300/h/300/q/85/upload/images/profile/xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx.png",
|
33
|
+
"medium_mobile": "http://images-mix.netdna-ssl.com/w/80/h/80/q/75/upload/images/profile/xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx.png",
|
34
|
+
"small": "http://images-mix.netdna-ssl.com/w/25/h/25/q/85/upload/images/profile/xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx.png",
|
35
|
+
"thumbnail": "http://images-mix.netdna-ssl.com/w/50/h/50/q/85/upload/images/profile/xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx.png"
|
36
|
+
}
|
37
|
+
},
|
38
|
+
"key": "/author/title/",
|
39
|
+
"created_time": "2011-06-12T10:40:19Z",
|
40
|
+
"audio_length": 1111,
|
41
|
+
"slug": "title",
|
42
|
+
"favorite_count": 11
|
43
|
+
}
|
File without changes
|
@@ -0,0 +1,91 @@
|
|
1
|
+
<html><head>
|
2
|
+
<meta name="keywords" content="">
|
3
|
+
<meta name="description" content="音ズレ修正">
|
4
|
+
<meta http-equiv="Pragma" content="no-cache">
|
5
|
+
<meta http-equiv="Cache-Control" content="no-store, no-cache, must-revalidate, post-check=0, pre-check=0">
|
6
|
+
<meta http-equiv="Expires" content="Thu, 01 Dec 1994 16:00:00 GMT">
|
7
|
+
<meta property="og:title" content="Title">
|
8
|
+
<meta property="og:description" content="This is a description.">
|
9
|
+
<meta property="og:type" content="video">
|
10
|
+
<meta property="og:video" content="http://ext.nicovideo.jp/thumb_watch/sm1111111?thumb_mode=swf&ap=1&c=1">
|
11
|
+
<meta property="og:video:width" content="485">
|
12
|
+
<meta property="og:video:height" content="385">
|
13
|
+
<meta property="og:video:type" content="application/x-shockwave-flash">
|
14
|
+
<meta property="og:site_name" content="Niconico">
|
15
|
+
<meta property="og:url" content="http://www.nicovideo.jp/watch/sm1111111">
|
16
|
+
<meta property="og:image" content="http://tn-skr2.smilevideo.jp/smile?i=1111111">
|
17
|
+
<meta property="og:locale:alternate" content="ja_JP"><meta property="og:locale:alternate" content="zh_TW"><meta property="og:locale" content="en_US">
|
18
|
+
<meta property="video:duration" content="1111">
|
19
|
+
<meta property="video:release_date" content="2012-01-01T00:00+0900">
|
20
|
+
<meta property="mixi:device-mobile" content="http://m.nicovideo.jp/watch/sm1111111?cp_webto=mixi_check_pc">
|
21
|
+
<meta property="mixi:device-docomo" content="http://m.nicovideo.jp/watch/sm1111111?uid=NULLGWDOCOMO&guid=ON&cp_webto=mixi_check_pc">
|
22
|
+
<link rel="alternate" media="handheld" href="http://nicomoba.jp/watch/sm1111111" />
|
23
|
+
<link rel="canonical" href="/watch/sm1111111">
|
24
|
+
<link rel="alternate" media="only screen and (max-width: 640px)" href="http://sp.nicovideo.jp/watch/sm1111111" />
|
25
|
+
<title>Title - niconico video Q</title>
|
26
|
+
</head>
|
27
|
+
|
28
|
+
<body>
|
29
|
+
<!--↓↓-->
|
30
|
+
<div style="width:144px; float:left; overflow:hidden;">
|
31
|
+
<p class="hLine"><img src="http://res.nimg.jp/img/watch/logout/icon_vinfo.png" alt="Video Info">Video Info</p>
|
32
|
+
<!--↓thumbnail↓-->
|
33
|
+
<div style="width:132px; border:solid 2px #C9CFCF; margin:4px;">
|
34
|
+
<p><img alt="" src="http://tn-skr2.smilevideo.jp/smile?i=1111111" class="img_std128"></p>
|
35
|
+
<p class="vinfo_length"><span>11:11</span></p>
|
36
|
+
</div>
|
37
|
+
<!--↑thumbnail↑-->
|
38
|
+
</div>
|
39
|
+
<div style="width:528px; float:left; overflow:hidden;">
|
40
|
+
<div style="padding:4px;">
|
41
|
+
<p class="font12" style="color:#696F6F; margin:0 0 4px;">
|
42
|
+
Uploaded on: <strong>Jan 1, 2012, 00:00</strong>
|
43
|
+
</p>
|
44
|
+
<!-- google_ad_section_start -->
|
45
|
+
<h1 itemprop="name">Title</h1>
|
46
|
+
<!-- google_ad_section_end -->
|
47
|
+
</div>
|
48
|
+
<table cellpadding="0" cellspacing="4" class="font12" style="clear:both;">
|
49
|
+
<tr>
|
50
|
+
<td><img src="http://res.nimg.jp/img/x.gif" alt="Views " class="icon_view"></td>
|
51
|
+
<td>Views:<strong>11,111</strong></td>
|
52
|
+
</tr>
|
53
|
+
<tr>
|
54
|
+
<td><img src="http://res.nimg.jp/img/x.gif" alt="Comments " class="icon_comment"></td>
|
55
|
+
<td>Comments:<strong>1,111</strong></td>
|
56
|
+
</tr>
|
57
|
+
<tr>
|
58
|
+
<td><img src="http://res.nimg.jp/img/x.gif" alt="Uploader" class="icon_owner"></td>
|
59
|
+
<td itemprop="author" itemscope itemtype="http://schema.org/Person">
|
60
|
+
Uploader: <strong itemprop="name">Author</strong>
|
61
|
+
</td>
|
62
|
+
</tr>
|
63
|
+
</table>
|
64
|
+
</div>
|
65
|
+
|
66
|
+
|
67
|
+
|
68
|
+
<!--↑↑-->
|
69
|
+
|
70
|
+
<!--↓動画説明文↓-->
|
71
|
+
<div class="mb8p4" style="clear:both;">
|
72
|
+
<div id="des_full">
|
73
|
+
<p class="font12" style="color:#494F4F; margin:0 0 4px;"><strong>Video Description:</strong></p>
|
74
|
+
<!-- google_ad_section_start -->
|
75
|
+
<p class="font12" style="margin-left:16px;" itemprop="description">This is a description.</p>
|
76
|
+
<!-- google_ad_section_end -->
|
77
|
+
</div>
|
78
|
+
</div>
|
79
|
+
<!--↑動画説明文↑-->
|
80
|
+
|
81
|
+
<!--↓↓-->
|
82
|
+
<div class="mb8p4">
|
83
|
+
<p class="font12" style="color:#494F4F; margin:0 0 4px;"><strong>Registered tags:</strong></p>
|
84
|
+
<p class="font12" style="margin-left:16px;"><span style="color:#999F9F;">There are no registered tags</span></p>
|
85
|
+
</div>
|
86
|
+
<div class="mb8p4" style="clear:both;"><p class="dotline_2"></p></div>
|
87
|
+
<p class="font12" style="padding:4px;">You will need to <strong>log in</strong> before you can view videos.</p>
|
88
|
+
<div id="suggest_login" class="clearfix"><a href="https://secure.nicovideo.jp/secure/register" class="registerButton button">Register New Account</a><a href="https://secure.nicovideo.jp/secure/login_form?next_url=%2Fwatch%2Fsm1111111&site=niconico&time=1111111111&hash_key=1f1f1f1f" class="loginButton button">To log in screen</a></div><div id="ext_login" class="clearfix"><a href="https://secure.nicovideo.jp/secure/login_ext/facebook?site=niconico&next_url=%2Fwatch%2Fsm1111111" id="Login_fb" title="Login using Facebook"><img src="http://res.nimg.jp/img/watch/logout/icon_facebook.png"><span>Login using Facebook</span></a><p>You can log in using Facebook→ </p></div>
|
89
|
+
<!--↑↑-->
|
90
|
+
</body>
|
91
|
+
</html>
|
File without changes
|
@@ -0,0 +1,53 @@
|
|
1
|
+
{
|
2
|
+
"artwork_url": "http://i1.sndcdn.com/artworks-000011111111-1cfbic-large.jpg?5c687d0",
|
3
|
+
"attachments_uri": "http://api.soundcloud.com/tracks/11111111/attachments",
|
4
|
+
"bpm": null,
|
5
|
+
"comment_count": 0,
|
6
|
+
"commentable": true,
|
7
|
+
"created_at": "2012/01/01 00:08:00 +0000",
|
8
|
+
"description": "",
|
9
|
+
"download_count": 0,
|
10
|
+
"downloadable": false,
|
11
|
+
"duration": 111111,
|
12
|
+
"embeddable_by": "all",
|
13
|
+
"favoritings_count": 0,
|
14
|
+
"genre": "Garage",
|
15
|
+
"id": 11111111,
|
16
|
+
"isrc": "",
|
17
|
+
"key_signature": "",
|
18
|
+
"kind": "track",
|
19
|
+
"label_id": null,
|
20
|
+
"label_name": "",
|
21
|
+
"license": "all-rights-reserved",
|
22
|
+
"original_content_size": 1111111,
|
23
|
+
"original_format": "mp3",
|
24
|
+
"permalink": "permalink",
|
25
|
+
"permalink_url": "http://soundcloud.com/author/permalink",
|
26
|
+
"playback_count": 4,
|
27
|
+
"purchase_title": null,
|
28
|
+
"purchase_url": null,
|
29
|
+
"release": "",
|
30
|
+
"release_day": null,
|
31
|
+
"release_month": null,
|
32
|
+
"release_year": null,
|
33
|
+
"sharing": "public",
|
34
|
+
"state": "finished",
|
35
|
+
"stream_url": "http://api.soundcloud.com/tracks/11111111/stream",
|
36
|
+
"streamable": true,
|
37
|
+
"tag_list": "tag1 tag2 tag3",
|
38
|
+
"title": "Title",
|
39
|
+
"track_type": "",
|
40
|
+
"uri": "http://api.soundcloud.com/tracks/11111111",
|
41
|
+
"user": {
|
42
|
+
"avatar_url": "http://i1.sndcdn.com/avatars-000011111111-zzjvpd-large.jpg?5c687d0",
|
43
|
+
"id": 11111111,
|
44
|
+
"kind": "user",
|
45
|
+
"permalink": "author",
|
46
|
+
"permalink_url": "http://soundcloud.com/author",
|
47
|
+
"uri": "http://api.soundcloud.com/users/11111111",
|
48
|
+
"username": "Author"
|
49
|
+
},
|
50
|
+
"user_id": 11111111,
|
51
|
+
"video_url": null,
|
52
|
+
"waveform_url": "http://w1.sndcdn.com/XXXXXXXXXXXX_m.png"
|
53
|
+
}
|
File without changes
|
@@ -0,0 +1,262 @@
|
|
1
|
+
{
|
2
|
+
"version":"1.0",
|
3
|
+
"encoding":"UTF-8",
|
4
|
+
"entry":{
|
5
|
+
"xmlns":"http://www.w3.org/2005/Atom",
|
6
|
+
"xmlns$media":"http://search.yahoo.com/mrss/",
|
7
|
+
"xmlns$gd":"http://schemas.google.com/g/2005",
|
8
|
+
"xmlns$yt":"http://gdata.youtube.com/schemas/2007",
|
9
|
+
"gd$etag":"W/\"CEQDQX47eCp7I2A9WhNXF04.\"",
|
10
|
+
"id":{
|
11
|
+
"$t":"tag:youtube.com,2008:video:XXXXXXXXXXX"
|
12
|
+
},
|
13
|
+
"published":{
|
14
|
+
"$t":"2012-01-01T00:00:00.000Z"
|
15
|
+
},
|
16
|
+
"updated":{
|
17
|
+
"$t":"2012-01-01T00:00:00.000Z"
|
18
|
+
},
|
19
|
+
"category":[
|
20
|
+
{
|
21
|
+
"scheme":"http://schemas.google.com/g/2005#kind",
|
22
|
+
"term":"http://gdata.youtube.com/schemas/2007#video"
|
23
|
+
},
|
24
|
+
{
|
25
|
+
"scheme":"http://gdata.youtube.com/schemas/2007/categories.cat",
|
26
|
+
"term":"Music",
|
27
|
+
"label":"Music"
|
28
|
+
}
|
29
|
+
],
|
30
|
+
"title":{
|
31
|
+
"$t":"Title"
|
32
|
+
},
|
33
|
+
"content":{
|
34
|
+
"type":"application/x-shockwave-flash",
|
35
|
+
"src":"https://www.youtube.com/v/XXXXXXXXXXX?version=3&f=videos&app=youtube_gdata"
|
36
|
+
},
|
37
|
+
"link":[
|
38
|
+
{
|
39
|
+
"rel":"http://gdata.youtube.com/schemas/2007#video.in-response-to",
|
40
|
+
"type":"application/atom+xml",
|
41
|
+
"href":"https://gdata.youtube.com/feeds/api/videos/XXXXXXXXXXX"
|
42
|
+
},
|
43
|
+
{
|
44
|
+
"rel":"alternate",
|
45
|
+
"type":"text/html",
|
46
|
+
"href":"https://www.youtube.com/watch?v=XXXXXXXXXXX&feature=youtube_gdata"
|
47
|
+
},
|
48
|
+
{
|
49
|
+
"rel":"http://gdata.youtube.com/schemas/2007#video.responses",
|
50
|
+
"type":"application/atom+xml",
|
51
|
+
"href":"https://gdata.youtube.com/feeds/api/videos/XXXXXXXXXXX/responses"
|
52
|
+
},
|
53
|
+
{
|
54
|
+
"rel":"http://gdata.youtube.com/schemas/2007#video.related",
|
55
|
+
"type":"application/atom+xml",
|
56
|
+
"href":"https://gdata.youtube.com/feeds/api/videos/XXXXXXXXXXX/related"
|
57
|
+
},
|
58
|
+
{
|
59
|
+
"rel":"http://gdata.youtube.com/schemas/2007#mobile",
|
60
|
+
"type":"text/html",
|
61
|
+
"href":"https://m.youtube.com/details?v=XXXXXXXXXXX"
|
62
|
+
},
|
63
|
+
{
|
64
|
+
"rel":"http://gdata.youtube.com/schemas/2007#uploader",
|
65
|
+
"type":"application/atom+xml",
|
66
|
+
"href":"https://gdata.youtube.com/feeds/api/users/XXX-XXXXXXXXXXXXXXXXXX"
|
67
|
+
},
|
68
|
+
{
|
69
|
+
"rel":"self",
|
70
|
+
"type":"application/atom+xml",
|
71
|
+
"href":"https://gdata.youtube.com/feeds/api/videos/XXXXXXXXXXX"
|
72
|
+
}
|
73
|
+
],
|
74
|
+
"author":[
|
75
|
+
{
|
76
|
+
"name":{
|
77
|
+
"$t":"pogobat"
|
78
|
+
},
|
79
|
+
"uri":{
|
80
|
+
"$t":"https://gdata.youtube.com/feeds/api/users/Author"
|
81
|
+
},
|
82
|
+
"yt$userId":{
|
83
|
+
"$t":"XXX-XXXXXXXXXXXXXXXXXX"
|
84
|
+
}
|
85
|
+
}
|
86
|
+
],
|
87
|
+
"yt$accessControl":[
|
88
|
+
{
|
89
|
+
"action":"comment",
|
90
|
+
"permission":"allowed"
|
91
|
+
},
|
92
|
+
{
|
93
|
+
"action":"commentVote",
|
94
|
+
"permission":"allowed"
|
95
|
+
},
|
96
|
+
{
|
97
|
+
"action":"videoRespond",
|
98
|
+
"permission":"allowed"
|
99
|
+
},
|
100
|
+
{
|
101
|
+
"action":"rate",
|
102
|
+
"permission":"allowed"
|
103
|
+
},
|
104
|
+
{
|
105
|
+
"action":"embed",
|
106
|
+
"permission":"allowed"
|
107
|
+
},
|
108
|
+
{
|
109
|
+
"action":"list",
|
110
|
+
"permission":"allowed"
|
111
|
+
},
|
112
|
+
{
|
113
|
+
"action":"autoPlay",
|
114
|
+
"permission":"allowed"
|
115
|
+
},
|
116
|
+
{
|
117
|
+
"action":"syndicate",
|
118
|
+
"permission":"allowed"
|
119
|
+
}
|
120
|
+
],
|
121
|
+
"gd$comments":{
|
122
|
+
"gd$feedLink":{
|
123
|
+
"rel":"http://gdata.youtube.com/schemas/2007#comments",
|
124
|
+
"href":"https://gdata.youtube.com/feeds/api/videos/XXXXXXXXXXX/comments",
|
125
|
+
"countHint":11111
|
126
|
+
}
|
127
|
+
},
|
128
|
+
"media$group":{
|
129
|
+
"media$category":[
|
130
|
+
{
|
131
|
+
"$t":"Music",
|
132
|
+
"label":"Music",
|
133
|
+
"scheme":"http://gdata.youtube.com/schemas/2007/categories.cat"
|
134
|
+
}
|
135
|
+
],
|
136
|
+
"media$content":[
|
137
|
+
{
|
138
|
+
"url":"https://www.youtube.com/v/XXXXXXXXXXX?version=3&f=videos&app=youtube_gdata",
|
139
|
+
"type":"application/x-shockwave-flash",
|
140
|
+
"medium":"video",
|
141
|
+
"isDefault":"true",
|
142
|
+
"expression":"full",
|
143
|
+
"duration":111,
|
144
|
+
"yt$format":5
|
145
|
+
},
|
146
|
+
{
|
147
|
+
"url":"rtsp://v8.cache6.c.youtube.com/CiILENy73wIaGQkzQ5_8oAjEHhMYDSANFEgGUgZ2aWRlb3MM/0/0/0/video.3gp",
|
148
|
+
"type":"video/3gpp",
|
149
|
+
"medium":"video",
|
150
|
+
"expression":"full",
|
151
|
+
"duration":111,
|
152
|
+
"yt$format":1
|
153
|
+
},
|
154
|
+
{
|
155
|
+
"url":"rtsp://v4.cache4.c.youtube.com/CiILENy73wIaGQkzQ5_8oAjEHhMYESARFEgGUgZ2aWRlb3MM/0/0/0/video.3gp",
|
156
|
+
"type":"video/3gpp",
|
157
|
+
"medium":"video",
|
158
|
+
"expression":"full",
|
159
|
+
"duration":111,
|
160
|
+
"yt$format":6
|
161
|
+
}
|
162
|
+
],
|
163
|
+
"media$credit":[
|
164
|
+
{
|
165
|
+
"$t":"Author",
|
166
|
+
"role":"uploader",
|
167
|
+
"scheme":"urn:youtube",
|
168
|
+
"yt$display":"Author",
|
169
|
+
"yt$type":"partner"
|
170
|
+
}
|
171
|
+
],
|
172
|
+
"media$description":{
|
173
|
+
"$t":"This is a description.",
|
174
|
+
"type":"plain"
|
175
|
+
},
|
176
|
+
"media$keywords":{
|
177
|
+
|
178
|
+
},
|
179
|
+
"media$license":{
|
180
|
+
"$t":"youtube",
|
181
|
+
"type":"text/html",
|
182
|
+
"href":"http://www.youtube.com/t/terms"
|
183
|
+
},
|
184
|
+
"media$player":{
|
185
|
+
"url":"https://www.youtube.com/watch?v=XXXXXXXXXXX&feature=youtube_gdata_player"
|
186
|
+
},
|
187
|
+
"media$thumbnail":[
|
188
|
+
{
|
189
|
+
"url":"http://i.ytimg.com/vi/XXXXXXXXXXX/default.jpg",
|
190
|
+
"height":90,
|
191
|
+
"width":120,
|
192
|
+
"time":"00:03:16",
|
193
|
+
"yt$name":"default"
|
194
|
+
},
|
195
|
+
{
|
196
|
+
"url":"http://i.ytimg.com/vi/XXXXXXXXXXX/mqdefault.jpg",
|
197
|
+
"height":180,
|
198
|
+
"width":320,
|
199
|
+
"yt$name":"mqdefault"
|
200
|
+
},
|
201
|
+
{
|
202
|
+
"url":"http://i.ytimg.com/vi/XXXXXXXXXXX/hqdefault.jpg",
|
203
|
+
"height":360,
|
204
|
+
"width":480,
|
205
|
+
"yt$name":"hqdefault"
|
206
|
+
},
|
207
|
+
{
|
208
|
+
"url":"http://i.ytimg.com/vi/XXXXXXXXXXX/1.jpg",
|
209
|
+
"height":90,
|
210
|
+
"width":120,
|
211
|
+
"time":"00:01:11",
|
212
|
+
"yt$name":"start"
|
213
|
+
},
|
214
|
+
{
|
215
|
+
"url":"http://i.ytimg.com/vi/XXXXXXXXXXX/2.jpg",
|
216
|
+
"height":90,
|
217
|
+
"width":120,
|
218
|
+
"time":"00:01:11",
|
219
|
+
"yt$name":"middle"
|
220
|
+
},
|
221
|
+
{
|
222
|
+
"url":"http://i.ytimg.com/vi/XXXXXXXXXXX/3.jpg",
|
223
|
+
"height":90,
|
224
|
+
"width":120,
|
225
|
+
"time":"00:01:11",
|
226
|
+
"yt$name":"end"
|
227
|
+
}
|
228
|
+
],
|
229
|
+
"media$title":{
|
230
|
+
"$t":"Title",
|
231
|
+
"type":"plain"
|
232
|
+
},
|
233
|
+
"yt$duration":{
|
234
|
+
"seconds":"111"
|
235
|
+
},
|
236
|
+
"yt$uploaded":{
|
237
|
+
"$t":"2012-01-01T00:00:00.000Z"
|
238
|
+
},
|
239
|
+
"yt$uploaderId":{
|
240
|
+
"$t":"XXXXX-XXXXXXXXXXXXXXXXXX"
|
241
|
+
},
|
242
|
+
"yt$videoid":{
|
243
|
+
"$t":"XXXXXXXXXXX"
|
244
|
+
}
|
245
|
+
},
|
246
|
+
"gd$rating":{
|
247
|
+
"average":5.0000000,
|
248
|
+
"max":5,
|
249
|
+
"min":1,
|
250
|
+
"numRaters":11111,
|
251
|
+
"rel":"http://schemas.google.com/g/2005#overall"
|
252
|
+
},
|
253
|
+
"yt$statistics":{
|
254
|
+
"favoriteCount":"0",
|
255
|
+
"viewCount":"11111111"
|
256
|
+
},
|
257
|
+
"yt$rating":{
|
258
|
+
"numDislikes":"1111",
|
259
|
+
"numLikes":"11111"
|
260
|
+
}
|
261
|
+
}
|
262
|
+
}
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bremen
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-12-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: guard-minitest
|
@@ -43,7 +43,23 @@ dependencies:
|
|
43
43
|
- - ! '>='
|
44
44
|
- !ruby/object:Gem::Version
|
45
45
|
version: '0'
|
46
|
-
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: terminal-notifier-guard
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
description: integrated searcher of audio tracks on music sites
|
47
63
|
email:
|
48
64
|
- itzki.h@gmail.com
|
49
65
|
executables: []
|
@@ -70,10 +86,14 @@ files:
|
|
70
86
|
- spec/bremen/nicovideo_spec.rb
|
71
87
|
- spec/bremen/soundcloud_spec.rb
|
72
88
|
- spec/bremen/youtube_spec.rb
|
73
|
-
- spec/fixtures/
|
74
|
-
- spec/fixtures/
|
75
|
-
- spec/fixtures/
|
76
|
-
- spec/fixtures/
|
89
|
+
- spec/fixtures/mixcloud_multi.json
|
90
|
+
- spec/fixtures/mixcloud_single.json
|
91
|
+
- spec/fixtures/nicovideo_multi.html
|
92
|
+
- spec/fixtures/nicovideo_single.html
|
93
|
+
- spec/fixtures/soundcloud_multi.json
|
94
|
+
- spec/fixtures/soundcloud_single.json
|
95
|
+
- spec/fixtures/youtube_multi.json
|
96
|
+
- spec/fixtures/youtube_single.json
|
77
97
|
- spec/spec_helper.rb
|
78
98
|
homepage: https://github.com/itzki/bremen
|
79
99
|
licenses: []
|
@@ -98,14 +118,19 @@ rubyforge_project:
|
|
98
118
|
rubygems_version: 1.8.23
|
99
119
|
signing_key:
|
100
120
|
specification_version: 3
|
101
|
-
summary:
|
121
|
+
summary: Bremen provides common search interface for some music websites. it supports
|
122
|
+
YouTube, SoundCloud, MixCloud and Nicovideo
|
102
123
|
test_files:
|
103
124
|
- spec/bremen/mixcloud_spec.rb
|
104
125
|
- spec/bremen/nicovideo_spec.rb
|
105
126
|
- spec/bremen/soundcloud_spec.rb
|
106
127
|
- spec/bremen/youtube_spec.rb
|
107
|
-
- spec/fixtures/
|
108
|
-
- spec/fixtures/
|
109
|
-
- spec/fixtures/
|
110
|
-
- spec/fixtures/
|
128
|
+
- spec/fixtures/mixcloud_multi.json
|
129
|
+
- spec/fixtures/mixcloud_single.json
|
130
|
+
- spec/fixtures/nicovideo_multi.html
|
131
|
+
- spec/fixtures/nicovideo_single.html
|
132
|
+
- spec/fixtures/soundcloud_multi.json
|
133
|
+
- spec/fixtures/soundcloud_single.json
|
134
|
+
- spec/fixtures/youtube_multi.json
|
135
|
+
- spec/fixtures/youtube_single.json
|
111
136
|
- spec/spec_helper.rb
|