bremen 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/Guardfile +6 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +8 -0
- data/bremen.gemspec +22 -0
- data/lib/bremen/base.rb +22 -0
- data/lib/bremen/mixcloud.rb +42 -0
- data/lib/bremen/nicovideo.rb +47 -0
- data/lib/bremen/request.rb +14 -0
- data/lib/bremen/soundcloud.rb +48 -0
- data/lib/bremen/track.rb +11 -0
- data/lib/bremen/version.rb +3 -0
- data/lib/bremen/youtube.rb +45 -0
- data/lib/bremen.rb +8 -0
- data/spec/bremen/mixcloud_spec.rb +29 -0
- data/spec/bremen/nicovideo_spec.rb +29 -0
- data/spec/bremen/soundcloud_spec.rb +37 -0
- data/spec/bremen/youtube_spec.rb +29 -0
- data/spec/fixtures/mixcloud.json +50 -0
- data/spec/fixtures/nicovideo.html +44 -0
- data/spec/fixtures/soundcloud.json +55 -0
- data/spec/fixtures/youtube.json +241 -0
- data/spec/spec_helper.rb +6 -0
- metadata +111 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 itzki
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Bremen
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'bremen'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install bremen
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/bremen.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'bremen/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "bremen"
|
8
|
+
gem.version = Bremen::VERSION
|
9
|
+
gem.authors = ["itzki"]
|
10
|
+
gem.email = ["itzki.h@gmail.com"]
|
11
|
+
gem.description = %q{integrated searcher of audio track on music sites}
|
12
|
+
gem.summary = %q{integrated searcher of audio track on music sites}
|
13
|
+
gem.homepage = "https://github.com/itzki/bremen"
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_development_dependency 'guard-minitest', ['>= 0']
|
21
|
+
gem.add_development_dependency 'rb-fsevent', ['>= 0']
|
22
|
+
end
|
data/lib/bremen/base.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'bremen/track'
|
2
|
+
require 'bremen/request'
|
3
|
+
|
4
|
+
module Bremen
|
5
|
+
class Base
|
6
|
+
include Track
|
7
|
+
extend Request
|
8
|
+
|
9
|
+
class << self
|
10
|
+
attr_accessor :default_options
|
11
|
+
|
12
|
+
def find options = {}
|
13
|
+
convert_from_response(get(search_url(options)))
|
14
|
+
end
|
15
|
+
|
16
|
+
#abstract methods
|
17
|
+
def search_url options = {}; end
|
18
|
+
private
|
19
|
+
def convert_from_response response; end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'bremen/base'
|
3
|
+
|
4
|
+
module Bremen
|
5
|
+
class Mixcloud < Bremen::Base
|
6
|
+
BASE_URL = 'http://api.mixcloud.com/search/'
|
7
|
+
self.default_options = {
|
8
|
+
keyword: '',
|
9
|
+
limit: 20,
|
10
|
+
}
|
11
|
+
|
12
|
+
class << self
|
13
|
+
def search_url options = {}
|
14
|
+
options = default_options.merge(options)
|
15
|
+
query = {
|
16
|
+
q: options[:keyword],
|
17
|
+
limit: options[:limit],
|
18
|
+
type: 'cloudcast',
|
19
|
+
}
|
20
|
+
"#{BASE_URL}?#{build_query(query)}"
|
21
|
+
end
|
22
|
+
|
23
|
+
def from_api hash = {}
|
24
|
+
created_at = Time.parse(hash['created_time'])
|
25
|
+
new({
|
26
|
+
uid: hash['key'],
|
27
|
+
url: hash['url'],
|
28
|
+
title: hash['name'],
|
29
|
+
author: hash['user']['name'],
|
30
|
+
length: hash['audio_length'].to_i,
|
31
|
+
created_at: created_at,
|
32
|
+
updated_at: created_at,
|
33
|
+
})
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
def convert_from_response response
|
38
|
+
JSON.parse(response)['data'].map{|t| from_api(t) }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'bremen/base'
|
3
|
+
|
4
|
+
module Bremen
|
5
|
+
class Nicovideo < Bremen::Base
|
6
|
+
BASE_URL = 'http://www.nicovideo.jp/search/'
|
7
|
+
self.default_options = {
|
8
|
+
keyword: '',
|
9
|
+
sort: 'f', #n(newer commented)/v(viewed)/r(most commented)/m(listed)/f(uploaded)/l(duration)
|
10
|
+
order: 'd', #a(asc)/d(desc)
|
11
|
+
within: '', #1(24h)/2(1w)/3(1m)
|
12
|
+
length: '', #1(-5min)/2(20min-)
|
13
|
+
downloadable: '', #1(music downloadable)
|
14
|
+
}
|
15
|
+
|
16
|
+
class << self
|
17
|
+
def search_url options = {}
|
18
|
+
options = default_options.merge(options)
|
19
|
+
query = {
|
20
|
+
sort: options[:sort],
|
21
|
+
order: options[:order],
|
22
|
+
f_range: options[:within],
|
23
|
+
l_range: options[:length],
|
24
|
+
opt_md: options[:downloadable],
|
25
|
+
}
|
26
|
+
"#{BASE_URL}#{CGI.escape(options[:keyword])}?#{build_query(query)}"
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
def convert_from_response response
|
31
|
+
response.scan(%r{<div class="thumb_col_1">\n<!---->\n(.*?)\n<!---->\n</div></div>}m).flatten.map do |html|
|
32
|
+
uid = html.scan(%r{<table [^>]+ summary="(.+)">}).flatten.first
|
33
|
+
min, sec = html.scan(%r{<p class="vinfo_length"><span>([\d:]+)</span></p>}).flatten.first.to_s.split(':')
|
34
|
+
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
|
+
new({
|
36
|
+
uid: uid,
|
37
|
+
url: "http://www.nicovideo.jp/watch/#{uid}",
|
38
|
+
title: CGI.unescape(html.scan(%r{<a [^>]+ class="watch" [^>]+>(.+)</a>}).flatten.first.to_s),
|
39
|
+
length: min.to_i * 60 + sec.to_i,
|
40
|
+
created_at: created_at,
|
41
|
+
updated_at: created_at,
|
42
|
+
})
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'bremen/base'
|
3
|
+
|
4
|
+
module Bremen
|
5
|
+
class Soundcloud < Bremen::Base
|
6
|
+
BASE_URL = 'http://api.soundcloud.com/tracks.json'
|
7
|
+
self.default_options = {
|
8
|
+
keyword: '',
|
9
|
+
order: 'created_at', #created_at/hotness
|
10
|
+
limit: 50,
|
11
|
+
filter: '', #(all)/public/private/streamable/downloadable
|
12
|
+
}
|
13
|
+
|
14
|
+
class << self
|
15
|
+
attr_accessor :consumer_key
|
16
|
+
|
17
|
+
def search_url options = {}
|
18
|
+
raise %Q{"#{self.name}.consumer_key" must be set} unless consumer_key
|
19
|
+
options = default_options.merge(options)
|
20
|
+
query = {
|
21
|
+
q: options[:keyword],
|
22
|
+
order: options[:order],
|
23
|
+
limit: options[:limit],
|
24
|
+
filter: options[:filter],
|
25
|
+
consumer_key: consumer_key,
|
26
|
+
}
|
27
|
+
"#{BASE_URL}?#{build_query(query)}"
|
28
|
+
end
|
29
|
+
|
30
|
+
def from_api hash = {}
|
31
|
+
new({
|
32
|
+
uid: hash['id'],
|
33
|
+
url: hash['permalink_url'],
|
34
|
+
title: hash['title'],
|
35
|
+
author: hash['user']['username'],
|
36
|
+
length: (hash['duration'].to_i / 1000).round,
|
37
|
+
created_at: Time.parse(hash['created_at']),
|
38
|
+
updated_at: Time.parse(hash['created_at']),
|
39
|
+
})
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
def convert_from_response response
|
44
|
+
JSON.parse(response).map{|t| from_api(t) }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/bremen/track.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'bremen/base'
|
3
|
+
|
4
|
+
module Bremen
|
5
|
+
class Youtube < Bremen::Base
|
6
|
+
BASE_URL = 'http://gdata.youtube.com/feeds/api/videos/'
|
7
|
+
self.default_options = {
|
8
|
+
order: 'published', #relevance/published/viewCount/rating
|
9
|
+
limit: 25,
|
10
|
+
category: 'Music',
|
11
|
+
tag: '',
|
12
|
+
}
|
13
|
+
|
14
|
+
class << self
|
15
|
+
def search_url options = {}
|
16
|
+
options = default_options.merge(options)
|
17
|
+
query = {
|
18
|
+
vq: options[:keyword],
|
19
|
+
orderby: options[:order],
|
20
|
+
:"max-results" => options[:limit],
|
21
|
+
alt: 'json',
|
22
|
+
}
|
23
|
+
"#{BASE_URL}-/#{options[:category]}/#{options[:tag]}/?#{build_query(query)}"
|
24
|
+
end
|
25
|
+
|
26
|
+
def from_api hash = {}
|
27
|
+
uid = hash['id']['$t'].sub('http://gdata.youtube.com/feeds/api/videos/', '')
|
28
|
+
new({
|
29
|
+
uid: uid,
|
30
|
+
url: "http://www.youtube.com/watch?v=#{uid}",
|
31
|
+
title: hash['title']['$t'],
|
32
|
+
author: hash['author'].first['name']['$t'],
|
33
|
+
length: hash['media$group']['yt$duration']['seconds'].to_i,
|
34
|
+
created_at: Time.parse(hash['published']['$t']),
|
35
|
+
updated_at: Time.parse(hash['updated']['$t']),
|
36
|
+
})
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
def convert_from_response response
|
41
|
+
JSON.parse(response)['feed']['entry'].map{|t| from_api(t) }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/bremen.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
$:.unshift(File.expand_path('../../', __FILE__))
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Bremen::Mixcloud do
|
5
|
+
describe '.search_url' do
|
6
|
+
subject{ Bremen::Mixcloud.search_url(params) }
|
7
|
+
describe 'only keyword' do
|
8
|
+
let(:params){ {keyword: 'searchword'} }
|
9
|
+
it 'generate' do
|
10
|
+
subject.must_equal 'http://api.mixcloud.com/search/?q=searchword&limit=20&type=cloudcast'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe 'full params' do
|
15
|
+
let(:params){ {keyword: 'searchword', limit: 1} }
|
16
|
+
it 'generate' do
|
17
|
+
subject.must_equal 'http://api.mixcloud.com/search/?q=searchword&limit=1&type=cloudcast'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '.convert_from_response' do
|
23
|
+
subject{ Bremen::Mixcloud.send(:convert_from_response, response) }
|
24
|
+
let(:response){ fixture('mixcloud.json') }
|
25
|
+
it 'convert successfully' do
|
26
|
+
subject.first.title.must_equal 'Title'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
$:.unshift(File.expand_path('../../', __FILE__))
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Bremen::Nicovideo do
|
5
|
+
describe '.search_url' do
|
6
|
+
subject{ Bremen::Nicovideo.search_url(params) }
|
7
|
+
describe 'only keyword' do
|
8
|
+
let(:params){ {keyword: 'searchword'} }
|
9
|
+
it 'generate' do
|
10
|
+
subject.must_equal 'http://www.nicovideo.jp/search/searchword?sort=f&order=d&f_range=&l_range=&opt_md='
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe 'full params' do
|
15
|
+
let(:params){ {keyword: 'searchword', sort: 'n', order: 'a', within: 3, length: 2, downloadable: 1} }
|
16
|
+
it 'generate' do
|
17
|
+
subject.must_equal 'http://www.nicovideo.jp/search/searchword?sort=n&order=a&f_range=3&l_range=2&opt_md=1'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '.convert_from_response' do
|
23
|
+
subject{ Bremen::Nicovideo.send(:convert_from_response, response) }
|
24
|
+
let(:response){ fixture('nicovideo.html') }
|
25
|
+
it 'convert successfully' do
|
26
|
+
subject.first.title.must_equal 'Title'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
$:.unshift(File.expand_path('../../', __FILE__))
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Bremen::Soundcloud do
|
5
|
+
describe '.search_url' do
|
6
|
+
describe 'not set consumer_key' do
|
7
|
+
it 'raise error' do
|
8
|
+
lambda{ Bremen::Soundcloud.search_url }.must_raise RuntimeError
|
9
|
+
end
|
10
|
+
end
|
11
|
+
describe 'set consumer_key' do
|
12
|
+
before{ Bremen::Soundcloud.consumer_key = 'CK' }
|
13
|
+
subject{ Bremen::Soundcloud.search_url(params) }
|
14
|
+
describe 'only keyword' do
|
15
|
+
let(:params){ {keyword: 'searchword'} }
|
16
|
+
it 'generate' do
|
17
|
+
subject.must_equal 'http://api.soundcloud.com/tracks.json?q=searchword&order=created_at&limit=50&filter=&consumer_key=CK'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe 'full params' do
|
22
|
+
let(:params){ {keyword: 'searchword', order: 'hotness', limit: 1, filter: 'public'} }
|
23
|
+
it 'generate' do
|
24
|
+
subject.must_equal 'http://api.soundcloud.com/tracks.json?q=searchword&order=hotness&limit=1&filter=public&consumer_key=CK'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe '.convert_from_response' do
|
31
|
+
subject{ Bremen::Soundcloud.send(:convert_from_response, response) }
|
32
|
+
let(:response){ fixture('soundcloud.json') }
|
33
|
+
it 'convert successfully' do
|
34
|
+
subject.first.title.must_equal 'Title'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
$:.unshift(File.expand_path('../../', __FILE__))
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Bremen::Youtube do
|
5
|
+
describe '.search_url' do
|
6
|
+
subject{ Bremen::Youtube.search_url(params) }
|
7
|
+
describe 'only keyword' do
|
8
|
+
let(:params){ {keyword: 'searchword'} }
|
9
|
+
it 'generate' do
|
10
|
+
subject.must_equal 'http://gdata.youtube.com/feeds/api/videos/-/Music//?vq=searchword&orderby=published&max-results=25&alt=json'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe 'full params' do
|
15
|
+
let(:params){ {keyword: 'searchword', order: 'relevance', limit: 1, category: 'Entertainment', tag: 'game'} }
|
16
|
+
it 'generate' do
|
17
|
+
subject.must_equal 'http://gdata.youtube.com/feeds/api/videos/-/Entertainment/game/?vq=searchword&orderby=relevance&max-results=1&alt=json'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '.convert_from_response' do
|
23
|
+
subject{ Bremen::Youtube.send(:convert_from_response, response) }
|
24
|
+
let(:response){ fixture('youtube.json') }
|
25
|
+
it 'convert successfully' do
|
26
|
+
subject.first.title.must_equal 'Title'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
{
|
2
|
+
"paging": {
|
3
|
+
"next": "http://api.mixcloud.com/search/?q=searchword&type=cloudcast&limit=1&offset=1"
|
4
|
+
},
|
5
|
+
"data": [
|
6
|
+
{
|
7
|
+
"listener_count": 111,
|
8
|
+
"name": "Title",
|
9
|
+
"tags": [
|
10
|
+
{
|
11
|
+
"url": "http://www.mixcloud.com/tag/tag1/",
|
12
|
+
"name": "Inna",
|
13
|
+
"key": "/tag/tag1/"
|
14
|
+
}
|
15
|
+
],
|
16
|
+
"url": "http://www.mixcloud.com/author/title/",
|
17
|
+
"pictures": {
|
18
|
+
"medium": "http://images-mix.netdna-ssl.com/w/100/h/100/q/85/upload/images/extaudio/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.png",
|
19
|
+
"extra_large": "http://images-mix.netdna-ssl.com/w/600/h/600/q/85/upload/images/extaudio/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.png",
|
20
|
+
"large": "http://images-mix.netdna-ssl.com/w/300/h/300/q/85/upload/images/extaudio/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.png",
|
21
|
+
"medium_mobile": "http://images-mix.netdna-ssl.com/w/80/h/80/q/75/upload/images/extaudio/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.png",
|
22
|
+
"small": "http://images-mix.netdna-ssl.com/w/25/h/25/q/85/upload/images/extaudio/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.png",
|
23
|
+
"thumbnail": "http://images-mix.netdna-ssl.com/w/50/h/50/q/85/upload/images/extaudio/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.png"
|
24
|
+
},
|
25
|
+
"updated_time": "2012-01-01T00:00:00Z",
|
26
|
+
"play_count": 1111,
|
27
|
+
"comment_count": 1,
|
28
|
+
"percentage_music": 100,
|
29
|
+
"user": {
|
30
|
+
"url": "http://www.mixcloud.com/author/",
|
31
|
+
"username": "author",
|
32
|
+
"name": "Author",
|
33
|
+
"key": "/author/",
|
34
|
+
"pictures": {
|
35
|
+
"medium": "http://images-mix.netdna-ssl.com/w/100/h/100/q/85/upload/images/profile/xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx.png",
|
36
|
+
"extra_large": "http://images-mix.netdna-ssl.com/w/600/h/600/q/85/upload/images/profile/xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx.png",
|
37
|
+
"large": "http://images-mix.netdna-ssl.com/w/300/h/300/q/85/upload/images/profile/xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx.png",
|
38
|
+
"medium_mobile": "http://images-mix.netdna-ssl.com/w/80/h/80/q/75/upload/images/profile/xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx.png",
|
39
|
+
"small": "http://images-mix.netdna-ssl.com/w/25/h/25/q/85/upload/images/profile/xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx.png",
|
40
|
+
"thumbnail": "http://images-mix.netdna-ssl.com/w/50/h/50/q/85/upload/images/profile/xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx.png"
|
41
|
+
}
|
42
|
+
},
|
43
|
+
"key": "/author/title/",
|
44
|
+
"created_time": "2011-06-12T10:40:19Z",
|
45
|
+
"audio_length": 1111,
|
46
|
+
"slug": "title",
|
47
|
+
"favorite_count": 11
|
48
|
+
}
|
49
|
+
]
|
50
|
+
}
|
@@ -0,0 +1,44 @@
|
|
1
|
+
<html>
|
2
|
+
<body>
|
3
|
+
<div class="thumb_col_1">
|
4
|
+
<!---->
|
5
|
+
<table width="624" cellpadding="4" cellspacing="0" summary="sm11111111">
|
6
|
+
<tr valign="top">
|
7
|
+
<td><div id="item1" style="display:none;" onMouseover="showOBJ('thumb_uad_msg_sm11111111')" onMouseout="hideOBJ('thumb_uad_msg_sm11111111')">
|
8
|
+
<div id="thumb_uad_msg_sm11111111" style="display:none; position:absolute;">
|
9
|
+
<p id="item1_uad_comment" class="uad_comment"><span style="color:#666;">-</span></p>
|
10
|
+
</div>
|
11
|
+
</div>
|
12
|
+
<div id="item1_thumb" class="uad_thumbfrm">
|
13
|
+
<table cellspacing="0" cellpadding="0">
|
14
|
+
<tr>
|
15
|
+
<td onMouseover="showOBJ('thumb_uad_msg_sm11111111')" onMouseout="hideOBJ('thumb_uad_msg_sm11111111')">
|
16
|
+
<p><a href="watch/sm11111111"><img src="http://tn-skr4.smilevideo.jp/smile?i=11111111" alt="" class="img_std96"></a></p>
|
17
|
+
<p class="vinfo_length"><span>1:01</span></p>
|
18
|
+
</td>
|
19
|
+
<td class="font10" align="right"><div style="width:92px; overflow:hidden; padding-left:4px;"><nobr>Views: <strong class="vinfo_view">111</strong><br></nobr>
|
20
|
+
<nobr>Comments: <strong class="vinfo_res">1</strong><br></nobr>
|
21
|
+
<nobr>My Lists: <a href="mylistcomment/video/sm11111111" style="color:#393F3F;"><strong class="vinfo_mylist">9</strong></a><br></nobr>
|
22
|
+
<nobr>Ads: <a href="http://uad.nicovideo.jp/ads/?vid=sm11111111" style="color:#393F3F;"><strong id="item1_uad_point_number" class="vinfo_uadp">0</strong></a><br></nobr>
|
23
|
+
</div></td>
|
24
|
+
</tr>
|
25
|
+
</table>
|
26
|
+
</div>
|
27
|
+
</td>
|
28
|
+
<td style="background:url('http://res.nimg.jp/img/common/thumb/split_line.png') no-repeat bottom left; padding-bottom:6px;">
|
29
|
+
<div style="width:412px; overflow:hidden;">
|
30
|
+
<p class="font12 thumb_num">
|
31
|
+
|
32
|
+
|
33
|
+
Uploaded on: <strong>Nov 11, 2012, 00:00</strong>
|
34
|
+
</p>
|
35
|
+
<p class="font16" style="margin:2px 0;"><nobr><a href="watch/sm11111111" class="watch" title="Title">Title</a></nobr></p>
|
36
|
+
<p class="vinfo_description" title="This is a description.">This is a description.</p>
|
37
|
+
</div>
|
38
|
+
</td>
|
39
|
+
</tr>
|
40
|
+
</table>
|
41
|
+
<!---->
|
42
|
+
</div></div>
|
43
|
+
</body>
|
44
|
+
</html>
|
@@ -0,0 +1,55 @@
|
|
1
|
+
[
|
2
|
+
{
|
3
|
+
"artwork_url": "http://i1.sndcdn.com/artworks-000011111111-1cfbic-large.jpg?5c687d0",
|
4
|
+
"attachments_uri": "http://api.soundcloud.com/tracks/11111111/attachments",
|
5
|
+
"bpm": null,
|
6
|
+
"comment_count": 0,
|
7
|
+
"commentable": true,
|
8
|
+
"created_at": "2012/01/01 00:08:00 +0000",
|
9
|
+
"description": "",
|
10
|
+
"download_count": 0,
|
11
|
+
"downloadable": false,
|
12
|
+
"duration": 111111,
|
13
|
+
"embeddable_by": "all",
|
14
|
+
"favoritings_count": 0,
|
15
|
+
"genre": "Garage",
|
16
|
+
"id": 11111111,
|
17
|
+
"isrc": "",
|
18
|
+
"key_signature": "",
|
19
|
+
"kind": "track",
|
20
|
+
"label_id": null,
|
21
|
+
"label_name": "",
|
22
|
+
"license": "all-rights-reserved",
|
23
|
+
"original_content_size": 1111111,
|
24
|
+
"original_format": "mp3",
|
25
|
+
"permalink": "permalink",
|
26
|
+
"permalink_url": "http://soundcloud.com/author/permalink",
|
27
|
+
"playback_count": 4,
|
28
|
+
"purchase_title": null,
|
29
|
+
"purchase_url": null,
|
30
|
+
"release": "",
|
31
|
+
"release_day": null,
|
32
|
+
"release_month": null,
|
33
|
+
"release_year": null,
|
34
|
+
"sharing": "public",
|
35
|
+
"state": "finished",
|
36
|
+
"stream_url": "http://api.soundcloud.com/tracks/11111111/stream",
|
37
|
+
"streamable": true,
|
38
|
+
"tag_list": "tag1 tag2 tag3",
|
39
|
+
"title": "Title",
|
40
|
+
"track_type": "",
|
41
|
+
"uri": "http://api.soundcloud.com/tracks/11111111",
|
42
|
+
"user": {
|
43
|
+
"avatar_url": "http://i1.sndcdn.com/avatars-000011111111-zzjvpd-large.jpg?5c687d0",
|
44
|
+
"id": 11111111,
|
45
|
+
"kind": "user",
|
46
|
+
"permalink": "author",
|
47
|
+
"permalink_url": "http://soundcloud.com/author",
|
48
|
+
"uri": "http://api.soundcloud.com/users/11111111",
|
49
|
+
"username": "Author"
|
50
|
+
},
|
51
|
+
"user_id": 11111111,
|
52
|
+
"video_url": null,
|
53
|
+
"waveform_url": "http://w1.sndcdn.com/XXXXXXXXXXXX_m.png"
|
54
|
+
}
|
55
|
+
]
|
@@ -0,0 +1,241 @@
|
|
1
|
+
{
|
2
|
+
"encoding": "UTF-8",
|
3
|
+
"feed": {
|
4
|
+
"author": [
|
5
|
+
{
|
6
|
+
"name": {
|
7
|
+
"$t": "YouTube"
|
8
|
+
},
|
9
|
+
"uri": {
|
10
|
+
"$t": "http://www.youtube.com/"
|
11
|
+
}
|
12
|
+
}
|
13
|
+
],
|
14
|
+
"category": [
|
15
|
+
{
|
16
|
+
"scheme": "http://schemas.google.com/g/2005#kind",
|
17
|
+
"term": "http://gdata.youtube.com/schemas/2007#video"
|
18
|
+
}
|
19
|
+
],
|
20
|
+
"entry": [
|
21
|
+
{
|
22
|
+
"author": [
|
23
|
+
{
|
24
|
+
"name": {
|
25
|
+
"$t": "Author"
|
26
|
+
},
|
27
|
+
"uri": {
|
28
|
+
"$t": "http://gdata.youtube.com/feeds/api/users/Author"
|
29
|
+
}
|
30
|
+
}
|
31
|
+
],
|
32
|
+
"category": [
|
33
|
+
{
|
34
|
+
"scheme": "http://schemas.google.com/g/2005#kind",
|
35
|
+
"term": "http://gdata.youtube.com/schemas/2007#video"
|
36
|
+
},
|
37
|
+
{
|
38
|
+
"label": "Music",
|
39
|
+
"scheme": "http://gdata.youtube.com/schemas/2007/categories.cat",
|
40
|
+
"term": "Music"
|
41
|
+
}
|
42
|
+
],
|
43
|
+
"content": {
|
44
|
+
"$t": "This is a description.",
|
45
|
+
"type": "text"
|
46
|
+
},
|
47
|
+
"gd$comments": {
|
48
|
+
"gd$feedLink": {
|
49
|
+
"countHint": 0,
|
50
|
+
"href": "http://gdata.youtube.com/feeds/api/videos/XXXXXXXXXXX/comments",
|
51
|
+
"rel": "http://gdata.youtube.com/schemas/2007#comments"
|
52
|
+
}
|
53
|
+
},
|
54
|
+
"id": {
|
55
|
+
"$t": "http://gdata.youtube.com/feeds/api/videos/XXXXXXXXXXX"
|
56
|
+
},
|
57
|
+
"link": [
|
58
|
+
{
|
59
|
+
"href": "http://www.youtube.com/watch?v=XXXXXXXXXXX&feature=youtube_gdata",
|
60
|
+
"rel": "alternate",
|
61
|
+
"type": "text/html"
|
62
|
+
},
|
63
|
+
{
|
64
|
+
"href": "http://gdata.youtube.com/feeds/api/videos/XXXXXXXXXXX/responses",
|
65
|
+
"rel": "http://gdata.youtube.com/schemas/2007#video.responses",
|
66
|
+
"type": "application/atom+xml"
|
67
|
+
},
|
68
|
+
{
|
69
|
+
"href": "http://gdata.youtube.com/feeds/api/videos/XXXXXXXXXXX/related",
|
70
|
+
"rel": "http://gdata.youtube.com/schemas/2007#video.related",
|
71
|
+
"type": "application/atom+xml"
|
72
|
+
},
|
73
|
+
{
|
74
|
+
"href": "http://m.youtube.com/details?v=XXXXXXXXXXX",
|
75
|
+
"rel": "http://gdata.youtube.com/schemas/2007#mobile",
|
76
|
+
"type": "text/html"
|
77
|
+
},
|
78
|
+
{
|
79
|
+
"href": "http://gdata.youtube.com/feeds/api/videos/XXXXXXXXXXX",
|
80
|
+
"rel": "self",
|
81
|
+
"type": "application/atom+xml"
|
82
|
+
}
|
83
|
+
],
|
84
|
+
"media$group": {
|
85
|
+
"media$category": [
|
86
|
+
{
|
87
|
+
"$t": "Music",
|
88
|
+
"label": "Music",
|
89
|
+
"scheme": "http://gdata.youtube.com/schemas/2007/categories.cat"
|
90
|
+
}
|
91
|
+
],
|
92
|
+
"media$content": [
|
93
|
+
{
|
94
|
+
"duration": 308,
|
95
|
+
"expression": "full",
|
96
|
+
"isDefault": "true",
|
97
|
+
"medium": "video",
|
98
|
+
"type": "application/x-shockwave-flash",
|
99
|
+
"url": "http://www.youtube.com/v/XXXXXXXXXXX?version=3&f=videos&app=youtube_gdata",
|
100
|
+
"yt$format": 5
|
101
|
+
},
|
102
|
+
{
|
103
|
+
"duration": 308,
|
104
|
+
"expression": "full",
|
105
|
+
"medium": "video",
|
106
|
+
"type": "video/3gpp",
|
107
|
+
"url": "rtsp://v8.cache4.c.youtube.com/CiILENy73wIaGQn8RbFfqUC_OxMYDSANFEgGUgZ2aWRlb3MM/0/0/0/video.3gp",
|
108
|
+
"yt$format": 1
|
109
|
+
},
|
110
|
+
{
|
111
|
+
"duration": 308,
|
112
|
+
"expression": "full",
|
113
|
+
"medium": "video",
|
114
|
+
"type": "video/3gpp",
|
115
|
+
"url": "rtsp://v1.cache7.c.youtube.com/CiILENy73wIaGQn8RbFfqUC_OxMYESARFEgGUgZ2aWRlb3MM/0/0/0/video.3gp",
|
116
|
+
"yt$format": 6
|
117
|
+
}
|
118
|
+
],
|
119
|
+
"media$description": {
|
120
|
+
"$t": "This is a description.",
|
121
|
+
"type": "plain"
|
122
|
+
},
|
123
|
+
"media$keywords": {},
|
124
|
+
"media$player": [
|
125
|
+
{
|
126
|
+
"url": "http://www.youtube.com/watch?v=XXXXXXXXXXX&feature=youtube_gdata_player"
|
127
|
+
}
|
128
|
+
],
|
129
|
+
"media$thumbnail": [
|
130
|
+
{
|
131
|
+
"height": 360,
|
132
|
+
"time": "00:02:34",
|
133
|
+
"url": "http://i.ytimg.com/vi/XXXXXXXXXXX/0.jpg",
|
134
|
+
"width": 480
|
135
|
+
},
|
136
|
+
{
|
137
|
+
"height": 90,
|
138
|
+
"time": "00:01:17",
|
139
|
+
"url": "http://i.ytimg.com/vi/XXXXXXXXXXX/1.jpg",
|
140
|
+
"width": 120
|
141
|
+
},
|
142
|
+
{
|
143
|
+
"height": 90,
|
144
|
+
"time": "00:02:34",
|
145
|
+
"url": "http://i.ytimg.com/vi/XXXXXXXXXXX/2.jpg",
|
146
|
+
"width": 120
|
147
|
+
},
|
148
|
+
{
|
149
|
+
"height": 90,
|
150
|
+
"time": "00:03:51",
|
151
|
+
"url": "http://i.ytimg.com/vi/XXXXXXXXXXX/3.jpg",
|
152
|
+
"width": 120
|
153
|
+
}
|
154
|
+
],
|
155
|
+
"media$title": {
|
156
|
+
"$t": "Title",
|
157
|
+
"type": "plain"
|
158
|
+
},
|
159
|
+
"yt$duration": {
|
160
|
+
"seconds": "308"
|
161
|
+
}
|
162
|
+
},
|
163
|
+
"published": {
|
164
|
+
"$t": "2012-01-01T00:50:00.000Z"
|
165
|
+
},
|
166
|
+
"title": {
|
167
|
+
"$t": "Title",
|
168
|
+
"type": "text"
|
169
|
+
},
|
170
|
+
"updated": {
|
171
|
+
"$t": "2012-01-01T00:50:00.000Z"
|
172
|
+
},
|
173
|
+
"yt$hd": {},
|
174
|
+
"yt$statistics": {
|
175
|
+
"favoriteCount": "0",
|
176
|
+
"viewCount": "1"
|
177
|
+
}
|
178
|
+
}
|
179
|
+
],
|
180
|
+
"generator": {
|
181
|
+
"$t": "YouTube data API",
|
182
|
+
"uri": "http://gdata.youtube.com",
|
183
|
+
"version": "2.1"
|
184
|
+
},
|
185
|
+
"id": {
|
186
|
+
"$t": "http://gdata.youtube.com/feeds/api/videos"
|
187
|
+
},
|
188
|
+
"link": [
|
189
|
+
{
|
190
|
+
"href": "http://www.youtube.com",
|
191
|
+
"rel": "alternate",
|
192
|
+
"type": "text/html"
|
193
|
+
},
|
194
|
+
{
|
195
|
+
"href": "http://gdata.youtube.com/feeds/api/videos",
|
196
|
+
"rel": "http://schemas.google.com/g/2005#feed",
|
197
|
+
"type": "application/atom+xml"
|
198
|
+
},
|
199
|
+
{
|
200
|
+
"href": "http://gdata.youtube.com/feeds/api/videos/batch",
|
201
|
+
"rel": "http://schemas.google.com/g/2005#batch",
|
202
|
+
"type": "application/atom+xml"
|
203
|
+
},
|
204
|
+
{
|
205
|
+
"href": "http://gdata.youtube.com/feeds/api/videos/-/%7Bhttp%3A%2F%2Fgdata.youtube.com%2Fschemas%2F2007%2Fcategories.cat%7DMusic?alt=json&start-index=1&max-results=1&vq=searchword&orderby=published",
|
206
|
+
"rel": "self",
|
207
|
+
"type": "application/atom+xml"
|
208
|
+
},
|
209
|
+
{
|
210
|
+
"href": "http://gdata.youtube.com/feeds/api/videos/-/%7Bhttp%3A%2F%2Fgdata.youtube.com%2Fschemas%2F2007%2Fcategories.cat%7DMusic?alt=json&start-index=2&max-results=1&vq=searchword&orderby=published",
|
211
|
+
"rel": "next",
|
212
|
+
"type": "application/atom+xml"
|
213
|
+
}
|
214
|
+
],
|
215
|
+
"logo": {
|
216
|
+
"$t": "http://www.youtube.com/img/pic_youtubelogo_123x63.gif"
|
217
|
+
},
|
218
|
+
"openSearch$itemsPerPage": {
|
219
|
+
"$t": 1
|
220
|
+
},
|
221
|
+
"openSearch$startIndex": {
|
222
|
+
"$t": 1
|
223
|
+
},
|
224
|
+
"openSearch$totalResults": {
|
225
|
+
"$t": 1111
|
226
|
+
},
|
227
|
+
"title": {
|
228
|
+
"$t": "Videos matching: searchword",
|
229
|
+
"type": "text"
|
230
|
+
},
|
231
|
+
"updated": {
|
232
|
+
"$t": "2012-01-01T00:50:00.000Z"
|
233
|
+
},
|
234
|
+
"xmlns": "http://www.w3.org/2005/Atom",
|
235
|
+
"xmlns$gd": "http://schemas.google.com/g/2005",
|
236
|
+
"xmlns$media": "http://search.yahoo.com/mrss/",
|
237
|
+
"xmlns$openSearch": "http://a9.com/-/spec/opensearchrss/1.0/",
|
238
|
+
"xmlns$yt": "http://gdata.youtube.com/schemas/2007"
|
239
|
+
},
|
240
|
+
"version": "1.0"
|
241
|
+
}
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bremen
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- itzki
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-11-19 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: guard-minitest
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rb-fsevent
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
description: integrated searcher of audio track on music sites
|
47
|
+
email:
|
48
|
+
- itzki.h@gmail.com
|
49
|
+
executables: []
|
50
|
+
extensions: []
|
51
|
+
extra_rdoc_files: []
|
52
|
+
files:
|
53
|
+
- .gitignore
|
54
|
+
- Gemfile
|
55
|
+
- Guardfile
|
56
|
+
- LICENSE.txt
|
57
|
+
- README.md
|
58
|
+
- Rakefile
|
59
|
+
- bremen.gemspec
|
60
|
+
- lib/bremen.rb
|
61
|
+
- lib/bremen/base.rb
|
62
|
+
- lib/bremen/mixcloud.rb
|
63
|
+
- lib/bremen/nicovideo.rb
|
64
|
+
- lib/bremen/request.rb
|
65
|
+
- lib/bremen/soundcloud.rb
|
66
|
+
- lib/bremen/track.rb
|
67
|
+
- lib/bremen/version.rb
|
68
|
+
- lib/bremen/youtube.rb
|
69
|
+
- spec/bremen/mixcloud_spec.rb
|
70
|
+
- spec/bremen/nicovideo_spec.rb
|
71
|
+
- spec/bremen/soundcloud_spec.rb
|
72
|
+
- spec/bremen/youtube_spec.rb
|
73
|
+
- spec/fixtures/mixcloud.json
|
74
|
+
- spec/fixtures/nicovideo.html
|
75
|
+
- spec/fixtures/soundcloud.json
|
76
|
+
- spec/fixtures/youtube.json
|
77
|
+
- spec/spec_helper.rb
|
78
|
+
homepage: https://github.com/itzki/bremen
|
79
|
+
licenses: []
|
80
|
+
post_install_message:
|
81
|
+
rdoc_options: []
|
82
|
+
require_paths:
|
83
|
+
- lib
|
84
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
85
|
+
none: false
|
86
|
+
requirements:
|
87
|
+
- - ! '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
91
|
+
none: false
|
92
|
+
requirements:
|
93
|
+
- - ! '>='
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
requirements: []
|
97
|
+
rubyforge_project:
|
98
|
+
rubygems_version: 1.8.23
|
99
|
+
signing_key:
|
100
|
+
specification_version: 3
|
101
|
+
summary: integrated searcher of audio track on music sites
|
102
|
+
test_files:
|
103
|
+
- spec/bremen/mixcloud_spec.rb
|
104
|
+
- spec/bremen/nicovideo_spec.rb
|
105
|
+
- spec/bremen/soundcloud_spec.rb
|
106
|
+
- spec/bremen/youtube_spec.rb
|
107
|
+
- spec/fixtures/mixcloud.json
|
108
|
+
- spec/fixtures/nicovideo.html
|
109
|
+
- spec/fixtures/soundcloud.json
|
110
|
+
- spec/fixtures/youtube.json
|
111
|
+
- spec/spec_helper.rb
|