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