video_info 3.0.2 → 4.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.
@@ -1,7 +1,7 @@
1
1
  class VideoInfo
2
2
  module Providers
3
3
  module VimeoAPI
4
- THUMBNAIL_LINK_REGEX = /.*\/(\d+\-[^_]+)/
4
+ THUMBNAIL_LINK_REGEX = /.*\/(\d+-[^_]+)/
5
5
 
6
6
  def api_key
7
7
  VideoInfo.provider_api_keys[:vimeo]
@@ -16,24 +16,24 @@ class VideoInfo
16
16
  end
17
17
 
18
18
  def title
19
- _video['name']
19
+ _video["name"]
20
20
  end
21
21
 
22
22
  def author
23
- _video['user']['name']
23
+ _video["user"]["name"]
24
24
  end
25
25
 
26
26
  def author_thumbnail_id
27
- author_uri = _video['user']['pictures']['uri']
27
+ author_uri = _video["user"]["pictures"]["uri"]
28
28
  @author_thumbnail_id ||= parse_picture_id_from_user(author_uri)
29
29
  end
30
30
 
31
31
  def author_url
32
- _video['user']['link']
32
+ _video["user"]["link"]
33
33
  end
34
34
 
35
35
  def author_thumbnail(width = 75)
36
- 'https://i.vimeocdn.com/portrait/' \
36
+ "https://i.vimeocdn.com/portrait/" \
37
37
  "#{author_thumbnail_id}_#{width}x#{width}.jpg"
38
38
  end
39
39
 
@@ -58,15 +58,19 @@ class VideoInfo
58
58
  end
59
59
 
60
60
  def keywords_array
61
- _video['tags'].map { |t| t['tag'] }
61
+ _video["tags"].map { |t| t["tag"] }
62
62
  end
63
63
 
64
64
  def date
65
- Time.parse(_video['created_time'], Time.now.utc).utc
65
+ Time.parse(_video["created_time"], Time.now.utc).utc
66
66
  end
67
67
 
68
68
  def view_count
69
- _video['stats']['plays'].to_i
69
+ stats["plays"].to_i
70
+ end
71
+
72
+ def stats
73
+ _video["stats"]
70
74
  end
71
75
 
72
76
  private
@@ -86,15 +90,15 @@ class VideoInfo
86
90
  end
87
91
 
88
92
  def _api_version
89
- '3.2'
93
+ "3.2"
90
94
  end
91
95
 
92
96
  def _authorization_headers
93
- { 'Authorization' => "bearer #{api_key}" }
97
+ {"Authorization" => "bearer #{api_key}"}
94
98
  end
95
99
 
96
100
  def _api_version_headers
97
- { 'Accept' => "application/vnd.vimeo.*+json;version=#{_api_version}" }
101
+ {"Accept" => "application/vnd.vimeo.*+json;version=#{_api_version}"}
98
102
  end
99
103
 
100
104
  def _video
@@ -102,7 +106,7 @@ class VideoInfo
102
106
  end
103
107
 
104
108
  def _api_base
105
- 'api.vimeo.com'
109
+ "api.vimeo.com"
106
110
  end
107
111
 
108
112
  def _api_path
@@ -113,8 +117,8 @@ class VideoInfo
113
117
  "https://#{_api_base}#{_api_path}"
114
118
  end
115
119
 
116
- def parse_picture_id_from_user (uri)
117
- %r{\/pictures\/(\d+)}.match(uri)[1]
120
+ def parse_picture_id_from_user(uri)
121
+ %r{/pictures/(\d+)}.match(uri)[1]
118
122
  end
119
123
 
120
124
  def parse_picture_id(uri)
@@ -1,15 +1,12 @@
1
- require 'oga'
2
- require 'open-uri'
3
- require 'json'
4
- require 'openssl'
5
- require 'cgi'
1
+ require "oga"
2
+ require "cgi"
6
3
 
7
4
  class VideoInfo
8
5
  module Providers
9
6
  module VimeoScraper
10
7
  def author
11
8
  if available?
12
- json_info['author']['name']
9
+ json_info["author"]["name"]
13
10
  end
14
11
  end
15
12
 
@@ -18,8 +15,8 @@ class VideoInfo
18
15
  return nil
19
16
  end
20
17
 
21
- split_point = 'window.vimeo.clip_page_config ='
22
- script_tags = data.css('script')
18
+ split_point = "window.vimeo.clip_page_config ="
19
+ script_tags = data.css("script")
23
20
 
24
21
  script_index = script_tags.find_index do |x|
25
22
  x.text.include?(split_point)
@@ -31,12 +28,12 @@ class VideoInfo
31
28
 
32
29
  parsed_data = JSON.parse(split_script_text.split(";\n")[0])
33
30
 
34
- parsed_data['owner']['portrait']['src']
31
+ parsed_data["owner"]["portrait"]["src"]
35
32
  end
36
33
 
37
34
  def author_url
38
35
  if available?
39
- json_info['author']['url']
36
+ json_info["author"]["url"]
40
37
  end
41
38
  end
42
39
 
@@ -46,7 +43,7 @@ class VideoInfo
46
43
  if data.nil?
47
44
  is_available = false
48
45
  elsif is_available
49
- password_elements = data.css('.exception_title--password')
46
+ password_elements = data.css(".exception_title--password")
50
47
 
51
48
  unless password_elements.empty?
52
49
  is_available = false
@@ -57,23 +54,23 @@ class VideoInfo
57
54
  end
58
55
 
59
56
  def title
60
- meta_node_value('og:title')
57
+ meta_node_value("og:title")
61
58
  end
62
59
 
63
60
  def description
64
- meta_node_value('og:description')
61
+ meta_node_value("og:description")
65
62
  end
66
63
 
67
64
  def date
68
65
  if available?
69
- upload_date = json_info['uploadDate']
66
+ upload_date = json_info["uploadDate"]
70
67
  ISO8601::DateTime.new(upload_date).to_time
71
68
  end
72
69
  end
73
70
 
74
71
  def duration
75
72
  if available?
76
- duration = json_info['duration']
73
+ duration = json_info["duration"]
77
74
  ISO8601::Duration.new(duration).to_seconds.to_i
78
75
  end
79
76
  end
@@ -83,54 +80,59 @@ class VideoInfo
83
80
  return nil
84
81
  end
85
82
 
86
- if json_info['keywords']
87
- json_info['keywords']
88
- else
89
- []
90
- end
83
+ json_info["keywords"] || []
91
84
  end
92
85
 
93
86
  def height
94
87
  if available?
95
- json_info['height']
88
+ json_info["height"]
96
89
  end
97
90
  end
98
91
 
99
92
  def width
100
93
  if available?
101
- json_info['width']
94
+ json_info["width"]
102
95
  end
103
96
  end
104
97
 
105
98
  def thumbnail_small
106
99
  if available?
107
- thumbnail_url.split('_')[0] + '_100x75.jpg'
100
+ thumbnail_url.split("_")[0] + "_100x75.jpg"
108
101
  end
109
102
  end
110
103
 
111
104
  def thumbnail_medium
112
105
  if available?
113
- thumbnail_url.split('_')[0] + '_200x150.jpg'
106
+ thumbnail_url.split("_")[0] + "_200x150.jpg"
114
107
  end
115
108
  end
116
109
 
117
110
  def thumbnail_large
118
111
  if available?
119
- thumbnail_url.split('_')[0] + '_640.jpg'
112
+ thumbnail_url.split("_")[0] + "_640.jpg"
120
113
  end
121
114
  end
122
115
 
123
116
  def view_count
124
117
  if available?
125
- user_interaction_count(interaction_type: "http://schema.org/WatchAction")
118
+ user_interaction_count(interaction_type: "WatchAction")
126
119
  end
127
120
  end
128
121
 
122
+ def stats
123
+ return {} unless available?
124
+ {
125
+ "plays" => view_count,
126
+ "likes" => user_interaction_count(interaction_type: "LikeAction"),
127
+ "comments" => user_interaction_count(interaction_type: "CommentAction")
128
+ }
129
+ end
130
+
129
131
  private
130
132
 
131
133
  def user_interaction_count(interaction_type:)
132
134
  interaction_statistic.find do |stat|
133
- stat["interactionType"] == interaction_type
135
+ stat["interactionType"] == "http://schema.org/#{interaction_type}"
134
136
  end["userInteractionCount"]
135
137
  end
136
138
 
@@ -139,39 +141,39 @@ class VideoInfo
139
141
  end
140
142
 
141
143
  def json_info
142
- @json_info ||= JSON.parse(data.css('script').detect do |n|
143
- type = n.attr('type')
144
+ @json_info ||= JSON.parse(data.css("script").detect do |n|
145
+ type = n.attr("type")
144
146
 
145
147
  if type.nil?
146
148
  false
147
149
  else
148
- type.value == 'application/ld+json'
150
+ type.value == "application/ld+json"
149
151
  end
150
152
  end.text)[0]
151
153
  end
152
154
 
153
155
  def thumbnail_url
154
- @thumbnail_url ||= remove_overlay(meta_node_value('og:image'))
156
+ @thumbnail_url ||= remove_overlay(meta_node_value("og:image"))
155
157
  end
156
158
 
157
159
  def remove_overlay(url)
158
160
  uri = URI.parse(url)
159
-
160
- if uri.path == '/filter/overlay'
161
- CGI::parse(uri.query)['src0'][0]
161
+
162
+ if uri.path == "/filter/overlay"
163
+ CGI.parse(uri.query)["src0"][0]
162
164
  else
163
165
  url
164
166
  end
165
167
  end
166
168
 
167
169
  def meta_nodes
168
- @meta_nodes ||= data.css('meta')
170
+ @meta_nodes ||= data.css("meta")
169
171
  end
170
172
 
171
173
  def meta_node_value(name)
172
174
  if available?
173
175
  node = meta_nodes.detect do |n|
174
- property = n.attr('property')
176
+ property = n.attr("property")
175
177
 
176
178
  if property.nil?
177
179
  false
@@ -180,20 +182,19 @@ class VideoInfo
180
182
  end
181
183
  end
182
184
 
183
- node.attr('content').value
185
+ node.attr("content").value
184
186
  end
185
187
  end
186
188
 
187
189
  def _set_data_from_api_impl(api_url)
188
- Oga.parse_html(URI.open(api_url.to_s).read)
189
-
190
+ Oga.parse_html(URI.parse(api_url.to_s).read)
190
191
  rescue OpenURI::HTTPError
191
192
  nil
192
193
  end
193
194
 
194
195
  def _api_url
195
196
  uri = URI.parse(@url)
196
- uri.scheme = 'https'
197
+ uri.scheme = "https"
197
198
  uri.to_s
198
199
  end
199
200
 
@@ -2,11 +2,11 @@ class VideoInfo
2
2
  module Providers
3
3
  class Wistia < Provider
4
4
  def self.usable?(url)
5
- url =~ /(.*)(wistia.com|wistia.net|wi.st)/
5
+ url.match?(/(.*)(wistia.com|wistia.net|wi.st)/)
6
6
  end
7
7
 
8
8
  def provider
9
- 'Wistia'
9
+ "Wistia"
10
10
  end
11
11
 
12
12
  %w[title duration width height].each do |method|
@@ -22,26 +22,26 @@ class VideoInfo
22
22
  end
23
23
 
24
24
  def thumbnail_small
25
- data['thumbnail_url']
25
+ data["thumbnail_url"]
26
26
  end
27
27
 
28
28
  def thumbnail_medium
29
- data['thumbnail_url']
29
+ data["thumbnail_url"]
30
30
  end
31
31
 
32
32
  def thumbnail_large
33
- data['thumbnail_url']
33
+ data["thumbnail_url"]
34
34
  end
35
35
 
36
36
  private
37
37
 
38
38
  def _url_regex
39
39
  %r{(?:.*)(?:wistia.com|wi.st|wistia.net)
40
- \/(?:embed\/)?(?:medias\/)?(?:iframe\/)?(.+)}x
40
+ /(?:embed/)?(?:medias/)?(?:iframe/)?(.+)}x
41
41
  end
42
42
 
43
43
  def _api_base
44
- 'fast.wistia.com'
44
+ "fast.wistia.com"
45
45
  end
46
46
 
47
47
  def _api_path
@@ -1,6 +1,6 @@
1
- require 'iso8601'
2
- require_relative 'youtube_api'
3
- require_relative 'youtube_scraper'
1
+ require "iso8601"
2
+ require_relative "youtube_api"
3
+ require_relative "youtube_scraper"
4
4
 
5
5
  class VideoInfo
6
6
  module Providers
@@ -16,12 +16,11 @@ class VideoInfo
16
16
  end
17
17
 
18
18
  def self.usable?(url)
19
- url =~ %r{(youtube\.com\/(?!playlist|embed\/videoseries).*)|
20
- (youtu\.be)}x
19
+ url.match?(/(youtube\.com\/(?!playlist|embed\/videoseries).*)|(youtu\.be)/)
21
20
  end
22
21
 
23
22
  def provider
24
- 'YouTube'
23
+ "YouTube"
25
24
  end
26
25
 
27
26
  %w[width height].each do |method|
@@ -55,12 +54,12 @@ class VideoInfo
55
54
  private
56
55
 
57
56
  def _url_regex
58
- %r{(?:youtube(?:-nocookie)?\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|
59
- .*[?&]v=)|youtu\.be\/)([^"&?\/ ]{11})}x
57
+ %r{(?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|
58
+ .*[?&]v=)|youtu\.be/)([^"&?/ ]{11})}x
60
59
  end
61
60
 
62
61
  def _default_iframe_attributes
63
- { allowfullscreen: 'allowfullscreen' }
62
+ {allowfullscreen: "allowfullscreen"}
64
63
  end
65
64
 
66
65
  def _default_url_attributes
@@ -2,9 +2,9 @@ class VideoInfo
2
2
  module Providers
3
3
  module YoutubeAPI
4
4
  def available?
5
- if !data['items'].empty?
6
- upload_status = data['items'][0]['status']['uploadStatus']
7
- 'rejected' != upload_status
5
+ if !data["items"].empty?
6
+ upload_status = data["items"][0]["status"]["uploadStatus"]
7
+ upload_status != "rejected"
8
8
  else
9
9
  false
10
10
  end
@@ -17,53 +17,58 @@ class VideoInfo
17
17
  end
18
18
 
19
19
  def author
20
- _video_snippet['channelTitle']
20
+ _video_snippet["channelTitle"]
21
21
  end
22
22
 
23
23
  def author_thumbnail
24
- _channel_snippet['thumbnails']['default']['url']
24
+ _channel_snippet["thumbnails"]["default"]["url"]
25
25
  end
26
26
 
27
27
  def author_url
28
- channel_id = _channel_info['items'][0]['id']
29
- 'https://www.youtube.com/channel/' + channel_id
28
+ channel_id = _channel_info["items"][0]["id"]
29
+ "https://www.youtube.com/channel/" + channel_id
30
30
  end
31
31
 
32
32
  def title
33
- _video_snippet['title']
33
+ _video_snippet["title"]
34
34
  end
35
35
 
36
36
  def description
37
- _video_snippet['description']
37
+ _video_snippet["description"]
38
38
  end
39
39
 
40
40
  def keywords
41
- _video_snippet['tags']
41
+ _video_snippet["tags"]
42
42
  end
43
43
 
44
44
  def duration
45
- video_duration = _video_content_details['duration'] || 0
45
+ video_duration = _video_content_details["duration"] || 0
46
46
  ISO8601::Duration.new(video_duration).to_seconds.to_i
47
47
  end
48
48
 
49
49
  def date
50
- return unless published_at = _video_snippet['publishedAt']
50
+ return unless (published_at = _video_snippet["publishedAt"])
51
51
  Time.parse(published_at, Time.now.utc)
52
52
  end
53
53
 
54
54
  def view_count
55
- _video_statistics['viewCount'].to_i
55
+ stats["viewCount"].to_i
56
+ end
57
+
58
+ def stats
59
+ return {} unless available?
60
+ data["items"][0]["statistics"]
56
61
  end
57
62
 
58
63
  private
59
64
 
60
65
  def _api_base
61
- 'www.googleapis.com'
66
+ "www.googleapis.com"
62
67
  end
63
68
 
64
69
  def _api_path
65
70
  "/youtube/v3/videos?id=#{video_id}" \
66
- '&part=snippet,statistics,status,contentDetails&fields=' \
71
+ "&part=snippet,statistics,status,contentDetails&fields=" \
67
72
  "items(id,snippet,statistics,status,contentDetails)&key=#{api_key}"
68
73
  end
69
74
 
@@ -73,7 +78,7 @@ class VideoInfo
73
78
 
74
79
  def _video_snippet
75
80
  return {} unless available?
76
- data['items'][0]['snippet']
81
+ data["items"][0]["snippet"]
77
82
  end
78
83
 
79
84
  def _channel_api_url(channel_id)
@@ -82,26 +87,21 @@ class VideoInfo
82
87
  end
83
88
 
84
89
  def _channel_info
85
- channel_url = _channel_api_url(_video_snippet['channelId'])
86
- @_channel_info ||= JSON.load(URI.open(channel_url).read)
90
+ channel_url = _channel_api_url(_video_snippet["channelId"])
91
+ @_channel_info ||= JSON.parse(URI.parse(channel_url).read)
87
92
  end
88
93
 
89
94
  def _channel_snippet
90
- _channel_info['items'][0]['snippet']
95
+ _channel_info["items"][0]["snippet"]
91
96
  end
92
97
 
93
98
  def _video_content_details
94
99
  return {} unless available?
95
- data['items'][0]['contentDetails']
96
- end
97
-
98
- def _video_statistics
99
- return {} unless available?
100
- data['items'][0]['statistics']
100
+ data["items"][0]["contentDetails"]
101
101
  end
102
102
 
103
103
  def _video_thumbnail(id)
104
- _video_entry['media$group']['media$thumbnail'][id]['url']
104
+ _video_entry["media$group"]["media$thumbnail"][id]["url"]
105
105
  end
106
106
  end
107
107
  end