video_info 1.2.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/video_info.rb +8 -36
- data/lib/video_info/provider.rb +58 -0
- data/lib/video_info/providers/vimeo.rb +42 -0
- data/lib/video_info/providers/youtube.rb +42 -0
- data/lib/video_info/version.rb +1 -1
- metadata +5 -4
- data/lib/providers/vimeo.rb +0 -45
- data/lib/providers/youtube.rb +0 -59
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 44fa17a8241b2ca3569f85f0629d413e14addcaf
|
4
|
+
data.tar.gz: 6755a66961813006fe5b1d2217a8ff8c274857dd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d10f94853d756b56ccc5a3fffd24f5dbe2f304ed3cd31a08aa1b72b1b9ed3ffe27173eab3a209e3a1c27ad54f7df4877b3937ecc0678286fde812aeaf9a43958
|
7
|
+
data.tar.gz: b146c0484a3e6346a72d61062301d49f0ecb8e247da901d14b5ec33844046dd868ce392211db33433442a80b22997523529fabd28232a87949cdba308ec709c8
|
data/lib/video_info.rb
CHANGED
@@ -1,47 +1,19 @@
|
|
1
|
-
require 'open-uri'
|
2
|
-
require 'multi_json'
|
3
1
|
require 'video_info/version'
|
4
|
-
require '
|
5
|
-
require 'providers/youtube'
|
2
|
+
require 'video_info/provider'
|
6
3
|
|
7
4
|
module VideoInfo
|
5
|
+
PROVIDERS = %w[Vimeo Youtube]
|
6
|
+
PROVIDERS.each { |p| require "video_info/providers/#{p.downcase}" }
|
8
7
|
|
9
8
|
def self.get(url, options = {})
|
10
|
-
|
11
|
-
|
12
|
-
valid?(video) ? video : nil
|
13
|
-
end
|
14
|
-
|
15
|
-
private
|
16
|
-
|
17
|
-
def self.get_video(url, options)
|
18
|
-
case url
|
19
|
-
when /vimeo\.com/
|
20
|
-
Vimeo.new(url, options)
|
21
|
-
when /(youtube\.com)|(youtu\.be)/
|
22
|
-
Youtube.new(url, options)
|
9
|
+
if provider_const = _providers_const.detect { |p| p.usable?(url) }
|
10
|
+
provider_const.new(url, options)
|
23
11
|
end
|
24
12
|
end
|
25
13
|
|
26
|
-
|
27
|
-
!video.nil? && !video.video_id.nil? && !['', nil].include?(video.title)
|
28
|
-
end
|
29
|
-
|
30
|
-
def self.clean_options(options)
|
31
|
-
options = { "User-Agent" => "VideoInfo/#{VideoInfo::VERSION}" }.merge options
|
32
|
-
options.dup.each do |key, value|
|
33
|
-
unless OpenURI::Options.keys.include?(key) || options[:iframe_attributes]
|
34
|
-
if key.is_a? Symbol
|
35
|
-
options[key.to_s.split(/[^a-z]/i).map(&:capitalize).join('-')] = value
|
36
|
-
options.delete key
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
options
|
41
|
-
end
|
14
|
+
private
|
42
15
|
|
43
|
-
def self.
|
44
|
-
|
45
|
-
" #{s}"
|
16
|
+
def self._providers_const
|
17
|
+
PROVIDERS.map { |p| Providers.const_get(p) }
|
46
18
|
end
|
47
19
|
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module VideoInfo
|
2
|
+
class Provider
|
3
|
+
|
4
|
+
attr_accessor :url, :options, :iframe_attributes, :video_id
|
5
|
+
attr_accessor :embed_url, :embed_code, :provider, :title, :description, :keywords,
|
6
|
+
:duration, :date, :width, :height,
|
7
|
+
:thumbnail_small, :thumbnail_medium, :thumbnail_large,
|
8
|
+
:view_count
|
9
|
+
|
10
|
+
def initialize(url, options = {}, iframe_attributes = nil)
|
11
|
+
@iframe_attributes = _hash_to_attributes(options.delete(:iframe_attributes))
|
12
|
+
@options = _clean_options(options)
|
13
|
+
@url = url
|
14
|
+
_set_video_id_from_url
|
15
|
+
_set_info_from_api if _valid_video_id?
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.usable?(url)
|
19
|
+
raise NotImplementedError.new('Provider class must implement .usable? public method')
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def _set_video_id_from_url
|
25
|
+
url.gsub(_url_regex) { @video_id = $1 || $2 || $3 }
|
26
|
+
end
|
27
|
+
|
28
|
+
def _valid_video_id?
|
29
|
+
video_id && video_id != url && !video_id.empty?
|
30
|
+
end
|
31
|
+
|
32
|
+
def _url_regex
|
33
|
+
raise NotImplementedError.new('Provider class must implement #_url_regex private method')
|
34
|
+
end
|
35
|
+
|
36
|
+
def _set_info_from_api
|
37
|
+
raise NotImplementedError.new('Provider class must implement #_set_info_from_api private method')
|
38
|
+
end
|
39
|
+
|
40
|
+
def _clean_options(options)
|
41
|
+
options = { 'User-Agent' => "VideoInfo/#{VideoInfo::VERSION}" }.merge(options)
|
42
|
+
options.dup.each do |key, value|
|
43
|
+
if key.is_a?(Symbol) && !OpenURI::Options.keys.include?(key)
|
44
|
+
options[key.to_s.split(/[^a-z]/i).map(&:capitalize).join('-')] = value
|
45
|
+
options.delete key
|
46
|
+
end
|
47
|
+
end
|
48
|
+
options
|
49
|
+
end
|
50
|
+
|
51
|
+
def _hash_to_attributes(hash)
|
52
|
+
if hash.is_a?(Hash)
|
53
|
+
s = hash.map{|k,v| "#{k}=\"#{v}\""}.join(' ')
|
54
|
+
" #{s}"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
require 'multi_json'
|
3
|
+
|
4
|
+
module VideoInfo
|
5
|
+
module Providers
|
6
|
+
class Vimeo < Provider
|
7
|
+
|
8
|
+
def self.usable?(url)
|
9
|
+
url =~ /vimeo\.com/
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def _url_regex
|
15
|
+
/.*\.com\/(?:groups\/[^\/]+\/videos\/)?([0-9]+).*$/i
|
16
|
+
end
|
17
|
+
|
18
|
+
def _set_info_from_api
|
19
|
+
uri = open("http://vimeo.com/api/v2/video/#{video_id}.json", options)
|
20
|
+
video = MultiJson.load(uri.read).first
|
21
|
+
@provider = "Vimeo"
|
22
|
+
@url = video['url']
|
23
|
+
@embed_url = "http://player.vimeo.com/video/#{video_id}"
|
24
|
+
@embed_code = "<iframe src=\"#{embed_url}?title=0&byline=0&portrait=0&autoplay=0\" frameborder=\"0\"#{iframe_attributes}></iframe>"
|
25
|
+
@title = video['title']
|
26
|
+
@description = video['description']
|
27
|
+
@keywords = video['tags']
|
28
|
+
@duration = video['duration'].to_i # seconds
|
29
|
+
@width = video['width'].to_i
|
30
|
+
@height = video['height'].to_i
|
31
|
+
@date = Time.parse(video['upload_date'], Time.now.utc).utc
|
32
|
+
@thumbnail_small = video['thumbnail_small']
|
33
|
+
@thumbnail_medium = video['thumbnail_medium']
|
34
|
+
@thumbnail_large = video['thumbnail_large']
|
35
|
+
@view_count = video['stats_number_of_plays'].to_i
|
36
|
+
rescue
|
37
|
+
nil
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
require 'multi_json'
|
3
|
+
|
4
|
+
module VideoInfo
|
5
|
+
module Providers
|
6
|
+
class Youtube < Provider
|
7
|
+
|
8
|
+
def self.usable?(url)
|
9
|
+
url =~ /(youtube\.com)|(youtu\.be)/
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def _url_regex
|
15
|
+
/youtube\.com\/.*\?v=([A-Za-z0-9._%-]*)?|youtu\.be\/([A-Za-z0-9._%-]*)?|youtube\.com\/embed\/([A-Za-z0-9._%-]*)?/
|
16
|
+
end
|
17
|
+
|
18
|
+
def _set_info_from_api
|
19
|
+
uri = open("http://gdata.youtube.com/feeds/api/videos/#{video_id}?v=2&alt=json", options)
|
20
|
+
video = MultiJson.load(uri.read)
|
21
|
+
@provider = "YouTube"
|
22
|
+
@url = url
|
23
|
+
@embed_url = "http://www.youtube.com/embed/#{video_id}"
|
24
|
+
@embed_code = "<iframe src=\"#{embed_url}\" frameborder=\"0\" allowfullscreen=\"allowfullscreen\"#{iframe_attributes}></iframe>"
|
25
|
+
video['entry'].tap do |entry|
|
26
|
+
@title = entry['title']['$t']
|
27
|
+
@description = entry['media$group']['media$description']['$t']
|
28
|
+
@keywords = entry['media$group']['media$keywords']['$t']
|
29
|
+
@duration = entry['media$group']['yt$duration']['seconds'].to_i
|
30
|
+
@date = Time.parse(entry['published']['$t'], Time.now.utc)
|
31
|
+
@thumbnail_small = entry['media$group']['media$thumbnail'][0]['url']
|
32
|
+
@thumbnail_medium = entry['media$group']['media$thumbnail'][1]['url']
|
33
|
+
@thumbnail_large = entry['media$group']['media$thumbnail'][2]['url']
|
34
|
+
@view_count = entry['yt$statistics'] ? entry['yt$statistics']['viewCount'].to_i : 0
|
35
|
+
end
|
36
|
+
rescue
|
37
|
+
nil
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/video_info/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: video_info
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thibaud Guillaume-Gentil
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-04-
|
11
|
+
date: 2013-04-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: multi_json
|
@@ -93,8 +93,9 @@ executables: []
|
|
93
93
|
extensions: []
|
94
94
|
extra_rdoc_files: []
|
95
95
|
files:
|
96
|
-
- lib/
|
97
|
-
- lib/providers/
|
96
|
+
- lib/video_info/provider.rb
|
97
|
+
- lib/video_info/providers/vimeo.rb
|
98
|
+
- lib/video_info/providers/youtube.rb
|
98
99
|
- lib/video_info/version.rb
|
99
100
|
- lib/video_info.rb
|
100
101
|
- LICENSE
|
data/lib/providers/vimeo.rb
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
module VideoInfo
|
2
|
-
class Vimeo
|
3
|
-
attr_accessor :video_id, :embed_url, :embed_code, :url, :provider, :title, :description, :keywords,
|
4
|
-
:duration, :date, :width, :height,
|
5
|
-
:thumbnail_small, :thumbnail_medium, :thumbnail_large,
|
6
|
-
:view_count,
|
7
|
-
:openURI_options
|
8
|
-
|
9
|
-
def initialize(url, options = {})
|
10
|
-
if iframe_attributes = options.delete(:iframe_attributes)
|
11
|
-
@iframe_attributes = VideoInfo.hash_to_attributes iframe_attributes
|
12
|
-
end
|
13
|
-
|
14
|
-
@openURI_options = options
|
15
|
-
@video_id = url.gsub(/.*\.com\/(?:groups\/[^\/]+\/videos\/)?([0-9]+).*$/i, '\1')
|
16
|
-
get_info unless @video_id == url || @video_id.nil? || @video_id.empty?
|
17
|
-
end
|
18
|
-
|
19
|
-
private
|
20
|
-
|
21
|
-
def get_info
|
22
|
-
begin
|
23
|
-
uri = open("http://vimeo.com/api/v2/video/#{@video_id}.json", @openURI_options)
|
24
|
-
video = MultiJson.load(uri.read).first
|
25
|
-
@provider = "Vimeo"
|
26
|
-
@url = video['url']
|
27
|
-
@embed_url = "http://player.vimeo.com/video/#{@video_id}"
|
28
|
-
@embed_code = "<iframe src=\"#{@embed_url}?title=0&byline=0&portrait=0&autoplay=0\" frameborder=\"0\"#{@iframe_attributes}></iframe>"
|
29
|
-
@title = video['title']
|
30
|
-
@description = video['description']
|
31
|
-
@keywords = video['tags']
|
32
|
-
@duration = video['duration'].to_i # seconds
|
33
|
-
@width = video['width'].to_i
|
34
|
-
@height = video['height'].to_i
|
35
|
-
@date = Time.parse(video['upload_date'], Time.now.utc).utc
|
36
|
-
@thumbnail_small = video['thumbnail_small']
|
37
|
-
@thumbnail_medium = video['thumbnail_medium']
|
38
|
-
@thumbnail_large = video['thumbnail_large']
|
39
|
-
@view_count = video['stats_number_of_plays'].to_i
|
40
|
-
rescue
|
41
|
-
nil
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
data/lib/providers/youtube.rb
DELETED
@@ -1,59 +0,0 @@
|
|
1
|
-
module VideoInfo
|
2
|
-
class Youtube
|
3
|
-
attr_accessor :video_id, :embed_url, :embed_code, :url, :provider, :title, :description, :keywords,
|
4
|
-
:duration, :date, :width, :height,
|
5
|
-
:thumbnail_small, :thumbnail_medium, :thumbnail_large,
|
6
|
-
:view_count,
|
7
|
-
:openURI_options
|
8
|
-
|
9
|
-
def initialize(url, options = {})
|
10
|
-
if iframe_attributes = options.delete(:iframe_attributes)
|
11
|
-
@iframe_attributes = VideoInfo.hash_to_attributes iframe_attributes
|
12
|
-
end
|
13
|
-
|
14
|
-
@openURI_options = options
|
15
|
-
video_id_for(url)
|
16
|
-
get_info unless @video_id == url || @video_id.nil? || @video_id.empty?
|
17
|
-
end
|
18
|
-
|
19
|
-
def regex
|
20
|
-
/youtube\.com\/watch\?v=([A-Za-z0-9._%-]*)?|youtu\.be\/([A-Za-z0-9._%-]*)?|youtube\.com\/embed\/([A-Za-z0-9._%-]*)?/
|
21
|
-
end
|
22
|
-
|
23
|
-
def video_id_for(url)
|
24
|
-
url.gsub(regex) do
|
25
|
-
@video_id = $1 || $2 || $3
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
private
|
30
|
-
|
31
|
-
def get_info
|
32
|
-
begin
|
33
|
-
uri = open("http://gdata.youtube.com/feeds/api/videos/#{@video_id}?v=2&alt=json", @openURI_options)
|
34
|
-
video = MultiJson.load(uri.read)
|
35
|
-
@provider = "YouTube"
|
36
|
-
@url = "http://www.youtube.com/watch?v=#{@video_id}"
|
37
|
-
@embed_url = "http://www.youtube.com/embed/#{@video_id}"
|
38
|
-
@embed_code = "<iframe src=\"#{@embed_url}\" frameborder=\"0\" allowfullscreen=\"allowfullscreen\"#{@iframe_attributes}></iframe>"
|
39
|
-
@title = video['entry']['title']['$t']
|
40
|
-
@description = video['entry']['media$group']['media$description']['$t']
|
41
|
-
@keywords = video['entry']['media$group']['media$keywords']['$t']
|
42
|
-
@duration = video['entry']['media$group']['yt$duration']['seconds'].to_i
|
43
|
-
@date = Time.parse(video['entry']['published']['$t'], Time.now.utc)
|
44
|
-
@thumbnail_small = video['entry']['media$group']['media$thumbnail'][0]['url']
|
45
|
-
@thumbnail_medium = video['entry']['media$group']['media$thumbnail'][1]['url']
|
46
|
-
@thumbnail_large = video['entry']['media$group']['media$thumbnail'][2]['url']
|
47
|
-
# when your video still has no view, yt:statistics is not returned by Youtube
|
48
|
-
# see: https://github.com/thibaudgg/video_info/issues/2
|
49
|
-
if video['entry']['yt$statistics']
|
50
|
-
@view_count = video['entry']['yt$statistics']['viewCount'].to_i
|
51
|
-
else
|
52
|
-
@view_count = 0
|
53
|
-
end
|
54
|
-
rescue
|
55
|
-
nil
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|