video_info 0.4.0 → 1.0.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/README.md CHANGED
@@ -15,21 +15,21 @@ Usage
15
15
  -----
16
16
 
17
17
  ``` ruby
18
- video = VideoInfo.new("http://www.youtube.com/watch?v=mZqGqE0D0n4")
18
+ video = VideoInfo.get("http://www.youtube.com/watch?v=mZqGqE0D0n4")
19
19
 
20
20
  # video.video_id => "mZqGqE0D0n4"
21
21
  # video.provider => "YouTube"
22
22
  # video.title => "Cherry Bloom - King Of The Knife"
23
23
  # video.description => "The first video from the upcoming album Secret Sounds, to download in-stores April 14. Checkout http://www.cherrybloom.net"
24
- # video.keywords => "alternative, bloom, cherry, clip, drum, guitar, king, knife, of, Paris-Forum, rock, the, tremplin"
25
24
  # video.duration => 175 (in seconds)
26
25
  # video.date => Sat Apr 12 22:25:35 UTC 2008
27
- # video.thumbnail_small => "http://i.ytimg.com/vi/mZqGqE0D0n4/2.jpg"
28
- # video.thumbnail_large => "http://i.ytimg.com/vi/mZqGqE0D0n4/0.jpg"
26
+ # video.thumbnail_small => "http://i.ytimg.com/vi/mZqGqE0D0n4/default.jpg"
27
+ # video.thumbnail_medium => "http://i.ytimg.com/vi/mZqGqE0D0n4/mqdefault.jpg"
28
+ # video.thumbnail_large => "http://i.ytimg.com/vi/mZqGqE0D0n4/hqdefault.jpg"
29
29
  # video.embed_url => "http://www.youtube.com/embed/mZqGqE0D0n4"
30
30
  # video.embed_code => "'<iframe src="http://www.youtube.com/embed/mZqGqE0D0n4" frameborder="0" allowfullscreen="allowfullscreen"></iframe>'"
31
31
 
32
- video = VideoInfo.new("http://vimeo.com/898029")
32
+ video = VideoInfo.get("http://vimeo.com/898029")
33
33
 
34
34
  # video.video_id => "898029"
35
35
  # video.provider => "Vimeo"
@@ -40,29 +40,26 @@ Usage
40
40
  # video.date => Mon Apr 14 13:10:39 +0200 2008
41
41
  # video.width => 640
42
42
  # video.height => 360
43
- # video.thumbnail_small => "http://ts.vimeo.com.s3.amazonaws.com/343/731/34373130_100.jpg"
44
- # video.thumbnail_large => "http://ts.vimeo.com.s3.amazonaws.com/343/731/34373130_640.jpg"
43
+ # video.thumbnail_small => "http://b.vimeocdn.com/ts/343/731/34373130_100.jpg"
44
+ # video.thumbnail_medium => "http://b.vimeocdn.com/ts/343/731/34373130_200.jpg"
45
+ # video.thumbnail_large => "http://b.vimeocdn.com/ts/343/731/34373130_640.jpg"
45
46
  # video.embed_url => "http://player.vimeo.com/video/898029"
46
47
  # video.embed_code => "'<iframe src="http://player.vimeo.com/video/898029?title=0&amp;byline=0&amp;portrait=0&amp;autoplay=0" frameborder="0"></iframe>'"
47
-
48
- video = VideoInfo.new("http://badurl.com/898029")
49
-
50
- # video.valid? => false
51
48
  ```
52
49
 
53
50
  Options
54
51
  -------
55
52
 
56
53
  ``` ruby
57
- video = VideoInfo.new("http://www.youtube.com/watch?v=mZqGqE0D0n4", "User-Agent" => "My Youtube Mashup Robot/1.0")
58
- video = VideoInfo.new("http://www.youtube.com/watch?v=mZqGqE0D0n4", "Referer" => "http://my-youtube-mashup.com/")
59
- video = VideoInfo.new("http://www.youtube.com/watch?v=mZqGqE0D0n4", "Referer" => "http://my-youtube-mashup.com/",
54
+ video = VideoInfo.get("http://www.youtube.com/watch?v=mZqGqE0D0n4", "User-Agent" => "My Youtube Mashup Robot/1.0")
55
+ video = VideoInfo.get("http://www.youtube.com/watch?v=mZqGqE0D0n4", "Referer" => "http://my-youtube-mashup.com/")
56
+ video = VideoInfo.get("http://www.youtube.com/watch?v=mZqGqE0D0n4", "Referer" => "http://my-youtube-mashup.com/",
60
57
  "User-Agent" => "My Youtube Mashup Robot/1.0")
61
58
  ```
62
59
  You can also use **symbols** instead of strings (any non-word (`/[^a-z]/i`) character would be converted to hyphen).
63
60
 
64
61
  ``` ruby
65
- video = VideoInfo.new("http://www.youtube.com/watch?v=mZqGqE0D0n4", :referer => "http://my-youtube-mashup.com/",
62
+ video = VideoInfo.get("http://www.youtube.com/watch?v=mZqGqE0D0n4", :referer => "http://my-youtube-mashup.com/",
66
63
  :user_agent => "My Youtube Mashup Robot/1.0")
67
64
  ```
68
65
 
@@ -73,7 +70,7 @@ It supports all openURI header fields (options), for more information see: [open
73
70
  You can also include an `iframe_attributes` hash to include arbitrary attributes in the iframe embed code:
74
71
 
75
72
  ``` ruby
76
- VideoInfo.new("http://www.youtube.com/watch?v=mZqGqE0D0n4", :iframe_attributes => { :width => 800, :height => 600, "data-key" => "value" } ).embed_code
73
+ VideoInfo.get("http://www.youtube.com/watch?v=mZqGqE0D0n4", :iframe_attributes => { :width => 800, :height => 600, "data-key" => "value" } ).embed_code
77
74
  => '<iframe src="http://www.youtube.com/embed/mZqGqE0D0n4" frameborder="0" allowfullscreen="allowfullscreen" width="800" height="600" data-key="value"></iframe>'
78
75
  ```
79
76
 
@@ -0,0 +1,49 @@
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
+ def valid?
20
+ !@video_id.nil? && !['', nil].include?(@title)
21
+ end
22
+
23
+ private
24
+
25
+ def get_info
26
+ begin
27
+ uri = open("http://vimeo.com/api/v2/video/#{@video_id}.json", @openURI_options)
28
+ video = MultiJson.load(uri.read).first
29
+ @provider = "Vimeo"
30
+ @url = video['url']
31
+ @embed_url = "http://player.vimeo.com/video/#{@video_id}"
32
+ @embed_code = "<iframe src=\"#{@embed_url}?title=0&amp;byline=0&amp;portrait=0&amp;autoplay=0\" frameborder=\"0\"#{@iframe_attributes}></iframe>"
33
+ @title = video['title']
34
+ @description = video['description']
35
+ @keywords = video['tags']
36
+ @duration = video['duration'].to_i # seconds
37
+ @width = video['width'].to_i
38
+ @height = video['height'].to_i
39
+ @date = Time.parse(video['upload_date'], Time.now.utc).utc
40
+ @thumbnail_small = video['thumbnail_small']
41
+ @thumbnail_medium = video['thumbnail_medium']
42
+ @thumbnail_large = video['thumbnail_large']
43
+ @view_count = video['stats_number_of_plays'].to_i
44
+ rescue
45
+ nil
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,63 @@
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
+ /youtu(.be)?(be.com)?.*(?:\/|v=)([\w-]+)/
21
+ end
22
+
23
+ def video_id_for(url)
24
+ url.gsub(regex) do
25
+ @video_id = $3
26
+ end
27
+ end
28
+
29
+ def valid?
30
+ !@video_id.nil? && !['', nil].include?(@title)
31
+ end
32
+
33
+ private
34
+
35
+ def get_info
36
+ begin
37
+ uri = open("http://gdata.youtube.com/feeds/api/videos/#{@video_id}?v=2&alt=json", @openURI_options)
38
+ video = MultiJson.load(uri.read)
39
+ @provider = "YouTube"
40
+ @url = "http://www.youtube.com/watch?v=#{@video_id}"
41
+ @embed_url = "http://www.youtube.com/embed/#{@video_id}"
42
+ @embed_code = "<iframe src=\"#{@embed_url}\" frameborder=\"0\" allowfullscreen=\"allowfullscreen\"#{@iframe_attributes}></iframe>"
43
+ @title = video['entry']['title']['$t']
44
+ @description = video['entry']['media$group']['media$description']['$t']
45
+ @keywords = video['entry']['media$group']['media$keywords']['$t']
46
+ @duration = video['entry']['media$group']['yt$duration']['seconds'].to_i
47
+ @date = Time.parse(video['entry']['published']['$t'], Time.now.utc)
48
+ @thumbnail_small = video['entry']['media$group']['media$thumbnail'][0]['url']
49
+ @thumbnail_medium = video['entry']['media$group']['media$thumbnail'][1]['url']
50
+ @thumbnail_large = video['entry']['media$group']['media$thumbnail'][2]['url']
51
+ # when your video still has no view, yt:statistics is not returned by Youtube
52
+ # see: https://github.com/thibaudgg/video_info/issues/2
53
+ if video['entry']['yt$statistics']
54
+ @view_count = video['entry']['yt$statistics']['viewCount'].to_i
55
+ else
56
+ @view_count = 0
57
+ end
58
+ rescue
59
+ nil
60
+ end
61
+ end
62
+ end
63
+ end
data/lib/video_info.rb CHANGED
@@ -1,15 +1,13 @@
1
1
  require 'open-uri'
2
- require 'hpricot'
2
+ require 'multi_json'
3
3
  require 'video_info/version'
4
- require 'provider/vimeo'
5
- require 'provider/youtube'
4
+ require 'providers/vimeo'
5
+ require 'providers/youtube'
6
6
 
7
- class VideoInfo
8
-
9
- def initialize(url, options = {})
10
-
11
- options = { "User-Agent" => "VideoInfo/#{VideoInfoVersion::VERSION}" }.merge options
12
- options.dup.each do |key,value|
7
+ module VideoInfo
8
+ def self.get(url, options = {})
9
+ options = { "User-Agent" => "VideoInfo/#{VideoInfo::VERSION}" }.merge options
10
+ options.dup.each do |key, value|
13
11
  unless OpenURI::Options.keys.include?(key) || options[:iframe_attributes]
14
12
  if key.is_a? Symbol
15
13
  options[key.to_s.split(/[^a-z]/i).map(&:capitalize).join('-')] = value
@@ -21,18 +19,12 @@ class VideoInfo
21
19
  case url
22
20
  when /vimeo\.com/
23
21
  @video = Vimeo.new(url, options)
24
- when /youtube\.com/
25
- @video = Youtube.new(url, options)
26
- when /youtu\.be/
22
+ when /(youtube\.com)|(youtu\.be)/
27
23
  @video = Youtube.new(url, options)
28
24
  end
29
25
  end
30
26
 
31
- def valid?
32
- @video != nil && !["", nil].include?(title)
33
- end
34
-
35
- def method_missing(sym, *args, &block)
27
+ def self.method_missing(sym, *args, &block)
36
28
  @video.send sym, *args, &block
37
29
  end
38
30
 
@@ -40,5 +32,4 @@ class VideoInfo
40
32
  s = hash.map{|k,v| "#{k}=\"#{v}\""}.join(' ')
41
33
  " #{s}"
42
34
  end
43
-
44
35
  end
@@ -1,3 +1,3 @@
1
- module VideoInfoVersion
2
- VERSION = "0.4.0"
1
+ module VideoInfo
2
+ VERSION = "1.0.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: video_info
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 1.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,24 +9,24 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-18 00:00:00.000000000 Z
12
+ date: 2012-11-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
- name: hpricot
15
+ name: multi_json
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
- - - ~>
19
+ - - ! '>='
20
20
  - !ruby/object:Gem::Version
21
- version: 0.8.4
21
+ version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  none: false
26
26
  requirements:
27
- - - ~>
27
+ - - ! '>='
28
28
  - !ruby/object:Gem::Version
29
- version: 0.8.4
29
+ version: '0'
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: bundler
32
32
  requirement: !ruby/object:Gem::Requirement
@@ -48,17 +48,17 @@ dependencies:
48
48
  requirement: !ruby/object:Gem::Requirement
49
49
  none: false
50
50
  requirements:
51
- - - ~>
51
+ - - ! '>='
52
52
  - !ruby/object:Gem::Version
53
- version: '2.10'
53
+ version: '0'
54
54
  type: :development
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  none: false
58
58
  requirements:
59
- - - ~>
59
+ - - ! '>='
60
60
  - !ruby/object:Gem::Version
61
- version: '2.10'
61
+ version: '0'
62
62
  - !ruby/object:Gem::Dependency
63
63
  name: guard-rspec
64
64
  requirement: !ruby/object:Gem::Requirement
@@ -76,7 +76,7 @@ dependencies:
76
76
  - !ruby/object:Gem::Version
77
77
  version: '0'
78
78
  - !ruby/object:Gem::Dependency
79
- name: webmock
79
+ name: fakeweb
80
80
  requirement: !ruby/object:Gem::Requirement
81
81
  none: false
82
82
  requirements:
@@ -96,17 +96,17 @@ dependencies:
96
96
  requirement: !ruby/object:Gem::Requirement
97
97
  none: false
98
98
  requirements:
99
- - - ~>
99
+ - - ! '>='
100
100
  - !ruby/object:Gem::Version
101
- version: '1.11'
101
+ version: '0'
102
102
  type: :development
103
103
  prerelease: false
104
104
  version_requirements: !ruby/object:Gem::Requirement
105
105
  none: false
106
106
  requirements:
107
- - - ~>
107
+ - - ! '>='
108
108
  - !ruby/object:Gem::Version
109
- version: '1.11'
109
+ version: '0'
110
110
  description: Get video info from youtube and vimeo url.
111
111
  email:
112
112
  - thibaud@thibaud.me
@@ -114,8 +114,8 @@ executables: []
114
114
  extensions: []
115
115
  extra_rdoc_files: []
116
116
  files:
117
- - lib/provider/vimeo.rb
118
- - lib/provider/youtube.rb
117
+ - lib/providers/vimeo.rb
118
+ - lib/providers/youtube.rb
119
119
  - lib/video_info/version.rb
120
120
  - lib/video_info.rb
121
121
  - LICENSE
@@ -1,39 +0,0 @@
1
- class Vimeo
2
- attr_accessor :video_id, :embed_url, :embed_code, :url, :provider, :title, :description, :keywords,
3
- :duration, :date, :width, :height,
4
- :thumbnail_small, :thumbnail_large,
5
- :view_count,
6
- :openURI_options
7
-
8
- def initialize(url, options = {})
9
- @iframe_attributes = VideoInfo.hash_to_attributes options.delete(:iframe_attributes) if options[:iframe_attributes]
10
- @openURI_options = options
11
- @video_id = url.gsub(/.*\.com\/(?:groups\/[^\/]+\/videos\/)?([0-9]+).*$/i, '\1')
12
- get_info unless @video_id == url || @video_id.nil? || @video_id.empty?
13
- end
14
-
15
- private
16
-
17
- def get_info
18
- begin
19
- doc = Hpricot(open("http://vimeo.com/api/v2/video/#{@video_id}.xml", @openURI_options))
20
- @provider = "Vimeo"
21
- @url = doc.search("url").inner_text
22
- @embed_url = "http://player.vimeo.com/video/#{@video_id}"
23
- @embed_code = "<iframe src=\"#{@embed_url}?title=0&amp;byline=0&amp;portrait=0&amp;autoplay=0\" frameborder=\"0\"#{@iframe_attributes}></iframe>"
24
- @title = doc.search("title").inner_text
25
- @description = doc.search("description").inner_text
26
- @keywords = doc.search("tags").inner_text
27
- @duration = doc.search("duration").inner_text.to_i # seconds
28
- @width = doc.search("width").inner_text.to_i
29
- @height = doc.search("height").inner_text.to_i
30
- @date = Time.parse(doc.search("upload_date").inner_text, Time.now.utc).utc
31
- @thumbnail_small = doc.search("thumbnail_small").inner_text
32
- @thumbnail_large = doc.search("thumbnail_large").inner_text
33
- @view_count = doc.search("stats_number_of_plays").inner_text.to_i
34
- rescue
35
- nil
36
- end
37
- end
38
-
39
- end
@@ -1,53 +0,0 @@
1
- class Youtube
2
- attr_accessor :video_id, :embed_url, :embed_code, :url, :provider, :title, :description, :keywords,
3
- :duration, :date, :width, :height,
4
- :thumbnail_small, :thumbnail_large,
5
- :view_count,
6
- :openURI_options
7
-
8
- def initialize(url, options = {})
9
- @iframe_attributes = VideoInfo.hash_to_attributes options.delete(:iframe_attributes) if options[:iframe_attributes]
10
- @openURI_options = options
11
- video_id_for(url)
12
- get_info unless @video_id == url || @video_id.nil? || @video_id.empty?
13
- end
14
-
15
- def regex
16
- /youtu(.be)?(be.com)?.*(?:\/|v=)([\w-]+)/
17
- end
18
-
19
- def video_id_for(url)
20
- url.gsub(regex) do
21
- @video_id = $3
22
- end
23
- end
24
-
25
- private
26
-
27
- def get_info
28
- begin
29
- doc = Hpricot(open("http://gdata.youtube.com/feeds/api/videos/#{@video_id}", @openURI_options))
30
- @provider = "YouTube"
31
- @url = "http://www.youtube.com/watch?v=#{@video_id}"
32
- @embed_url = "http://www.youtube.com/embed/#{@video_id}"
33
- @embed_code = "<iframe src=\"#{@embed_url}\" frameborder=\"0\" allowfullscreen=\"allowfullscreen\"#{@iframe_attributes}></iframe>"
34
- @title = doc.search("media:title").inner_text
35
- @description = doc.search("media:description").inner_text
36
- @keywords = doc.search("media:keywords").inner_text
37
- @duration = doc.search("yt:duration").first[:seconds].to_i
38
- @date = Time.parse(doc.search("published").inner_text, Time.now.utc)
39
- @thumbnail_small = doc.search("media:thumbnail").min { |a,b| a[:height].to_i * a[:width].to_i <=> b[:height].to_i * b[:width].to_i }[:url]
40
- @thumbnail_large = doc.search("media:thumbnail").max { |a,b| a[:height].to_i * a[:width].to_i <=> b[:height].to_i * b[:width].to_i }[:url]
41
- # when your video still has no view, yt:statistics is not returned by Youtube
42
- # see: https://github.com/thibaudgg/video_info/issues#issue/2
43
- if doc.search("yt:statistics").first
44
- @view_count = doc.search("yt:statistics").first[:viewcount].to_i
45
- else
46
- @view_count = 0
47
- end
48
- rescue
49
- nil
50
- end
51
- end
52
-
53
- end