video_info 1.2.0 → 1.3.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.
- 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
|