active_public_resources 0.2.4 → 0.2.9

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 750a849ad37794a269bab5b663992a2ee9101a10
4
- data.tar.gz: 17a0f5735242ebd52b93b020a3deb4a931ae3376
2
+ SHA256:
3
+ metadata.gz: 4ebe0286bc9284b369d5695587db96781a0d1154dce4999e982582f8e256a0e5
4
+ data.tar.gz: 37f81f8de8e1536edcc2768de8a89527889c4460d254c3769fad2a6e2ffcbae6
5
5
  SHA512:
6
- metadata.gz: d859e2ffb42e9b9dfa2b0e2bca4401de468d0e5aa34aeeb65e90b5a622436af796fadfe6014c1104b45fd12bdf10b77f10e032c8cd4c205f62aff20977b0e37d
7
- data.tar.gz: 9953aebb19aa8ea776f35d8b98e74d4e90115781f0cb8f8e47390baa67965231be473f841b4047dde577fadb4d7fa495d99bb0259dd66838d4f16a37713f55c5
6
+ metadata.gz: f068b798cf7f861a201aea160f81a16e1c6ec77aa23bba5a35dce85ec9b037fe316d44a390e33379ad30d2dc93466d0322ed34df5e8b8a61bf29ae4694e6d209
7
+ data.tar.gz: 192cc69228d7b0b02a7cc65583ee19d612b65a8355e491e806febd86e57d5a2c87d5653c8902a32da3cb7135f4baa86da7c324b466424fc50888e03e265fbe7c
data/Gemfile CHANGED
@@ -7,7 +7,7 @@ group :test do
7
7
  gem 'rspec', '~> 2.14.1'
8
8
  # gem 'rspec-mocks', '~> 2.14.4'
9
9
  gem 'vcr'
10
- gem 'webmock'
10
+ gem 'webmock', '~> 3.0.1'
11
11
  gem 'simplecov', '~> 0.8.1', :require => false
12
12
  gem 'growl'
13
13
  gem 'growl-rspec'
@@ -19,7 +19,7 @@ end
19
19
 
20
20
  group :development, :test do
21
21
  gem 'pry-remote'
22
- gem 'pry'
22
+ gem 'pry-byebug'
23
23
  end
24
24
 
25
25
  gemspec
data/README.md CHANGED
@@ -188,14 +188,12 @@ A driver in this context is a ruby class which performs requests and returns a r
188
188
 
189
189
  To use the Vimeo API, you must have credentials already. This requires a Vimeo app to
190
190
  be registered. You can do it at [https://developer.vimeo.com/apps](https://developer.vimeo.com/apps).
191
- There are 4 params which are necessary to perform the requests:
191
+ There are two params which are necessary to perform the requests:
192
192
 
193
193
  | Name | Required? | Description
194
194
  | ------------------- |:---------:| -------------
195
195
  | consumer_key | Yes | Vimeo API Client ID
196
196
  | consumer_secret | Yes | Vimeo API Client Secret
197
- | access_token | Yes | Vimeo API OAuth Access Token
198
- | access_token_secret | Yes | Vimeo API OAuth Access Token Secret
199
197
 
200
198
  #### Return Types
201
199
 
@@ -204,22 +202,20 @@ Vimeo returns **Iframe** and **URL** return types.
204
202
  #### Example:
205
203
 
206
204
  ```ruby
207
- criteria = APR::RequestCriteria.new( query: "education" )
205
+ criteria = APR::RequestCriteria.new(query: "education")
208
206
 
209
207
  vimeo = APR::Drivers::Vimeo.new(
210
208
  :consumer_key => 'VIMEO_CONSUMER_KEY',
211
- :consumer_secret => 'VIMEO_CONSUMER_SECRET',
212
- :access_token => 'VIMEO_ACCESS_TOKEN',
213
- :access_token_secret => 'VIMEO_ACCESS_TOKEN_SECRET'
209
+ :consumer_secret => 'VIMEO_CONSUMER_SECRET'
214
210
  )
215
211
 
216
- results = vimeo.perform_request( criteria )
212
+ results = vimeo.perform_request(criteria)
217
213
  results.items.length # => 25
218
214
  results.total_items # => 145063
219
215
  results.next_criteria # => #<ActivePublicResources::RequestCriteria:0x007fa48392d388 @query="education", @page=2, @per_page=25>
220
216
  results.items.first.title # => "Kynect 'education'"
221
217
 
222
- more_results = vimeo.perform_request( results.next_criteria )
218
+ more_results = vimeo.perform_request(results.next_criteria)
223
219
  # ...
224
220
  ```
225
221
 
@@ -21,9 +21,7 @@ Gem::Specification.new do |spec|
21
21
  spec.add_dependency "activesupport", ">= 4.0.0"
22
22
  spec.add_dependency "activemodel", ">= 4.0.0"
23
23
  spec.add_dependency "iso8601", "~> 0.8.6"
24
-
25
- # Drivers
26
- spec.add_dependency "vimeo", "~> 1.5.3"
24
+ spec.add_dependency "httparty", "~> 0.15.6"
27
25
 
28
26
  spec.add_development_dependency "bundler", "~> 1.3"
29
27
  end
@@ -1,8 +1,6 @@
1
1
  vimeo:
2
2
  consumer_key: VIMEO_CONSUMER_KEY
3
3
  consumer_secret: VIMEO_CONSUMER_SECRET
4
- access_token: VIMEO_ACCESS_TOKEN
5
- access_token_secret: VIMEO_ACCESS_TOKEN_SECRET
6
4
  youtube:
7
5
  schooltube:
8
6
  khan_academy:
@@ -1,4 +1,5 @@
1
- require 'vimeo'
1
+ require_relative '../oauth/vimeo.rb'
2
+ require 'httparty'
2
3
 
3
4
  module ActivePublicResources
4
5
  module Drivers
@@ -18,18 +19,13 @@ module ActivePublicResources
18
19
  # @param [Hash] config_options the options which the vimeo gem requires
19
20
  # @option config_options [String] :consumer_key Vimeo consumer key (required)
20
21
  # @option config_options [String] :consumer_secret Vimeo consumer secret (required)
21
- # @option config_options [String] :access_token Vimeo access token (required)
22
- # @option config_options [String] :access_token_secret Vimeo access token secret (required)
23
22
  def initialize(config_options={})
24
- validate_options(config_options,
25
- [:consumer_key, :consumer_secret, :access_token, :access_token_secret])
26
-
27
- @client = ::Vimeo::Advanced::Video.new(
23
+ validate_options(config_options, [:consumer_key, :consumer_secret])
24
+ @client = ActivePublicResources::OAuth::Vimeo.new(
28
25
  config_options[:consumer_key],
29
- config_options[:consumer_secret],
30
- token: config_options[:access_token],
31
- secret: config_options[:access_token_secret]
26
+ config_options[:consumer_secret]
32
27
  )
28
+ @access_token = @client.get_access_token
33
29
  end
34
30
 
35
31
  # Perform search request to Vimeo with search criteria
@@ -84,16 +80,23 @@ module ActivePublicResources
84
80
  request_criteria.validate_presence!([:query])
85
81
  raise StandardError.new("driver has not been initialized properly") unless @client
86
82
 
87
- results = @client.search(request_criteria.query, {
88
- :page => request_criteria.page || 1,
89
- :per_page => request_criteria.per_page || 25,
90
- :full_response => 1,
91
- :sort => request_criteria.sort || "relevant",
92
- :user_id => nil,
93
- :content_filter => request_criteria.content_filter || 'safe'
94
- })
83
+ results = HTTParty.get('https://api.vimeo.com/videos',
84
+ query: {
85
+ query: request_criteria.query,
86
+ page: request_criteria.page || 1,
87
+ per_page: request_criteria.per_page || 25,
88
+ sort: 'relevant',
89
+ filter: 'content_rating',
90
+ filter_content_rating: 'safe'
91
+ },
92
+ headers: { "Authorization" => "Bearer #{@access_token}" }
93
+ )
95
94
 
96
- return parse_results(request_criteria, results)
95
+ return parse_results(request_criteria, JSON.parse(results)) unless results.code == 401
96
+ if !@client.verify_token?(@access_token)
97
+ @access_token = @client.get_access_token
98
+ perform_request(request_criteria) if !@access_token.blank?
99
+ end
97
100
  end
98
101
 
99
102
  private
@@ -126,15 +129,16 @@ module ActivePublicResources
126
129
  @driver_response = DriverResponse.new(
127
130
  :criteria => request_criteria,
128
131
  :next_criteria => next_criteria(request_criteria, results),
129
- :total_items => results['videos']['total'].to_i,
130
- :items => results['videos']['video'].map { |data| parse_video(data) }
132
+ :total_items => results['total'].to_i,
133
+ :items => results['data'].map { |data| parse_video(data) }
131
134
  )
132
135
  end
133
136
 
134
137
  def next_criteria(request_criteria, results)
135
- page = results['videos']['page'].to_i
136
- per_page = results['videos']['perpage'].to_i
137
- total = results['videos']['total'].to_i
138
+ total = results['total'].to_i
139
+ page = results['page'].to_i
140
+ per_page = results['per_page'].to_i
141
+
138
142
  if ((page * per_page) < total)
139
143
  return RequestCriteria.new({
140
144
  :query => request_criteria.query,
@@ -146,18 +150,18 @@ module ActivePublicResources
146
150
 
147
151
  def parse_video(data)
148
152
  video = ActivePublicResources::ResponseTypes::Video.new
149
- video.id = data['id']
150
- video.title = data['title']
151
- video.description = data['description']
152
- video.thumbnail_url = data['thumbnails']['thumbnail'][0]['_content']
153
- video.url = data['urls']['url'][0]['_content']
154
- video.embed_url = "https://player.vimeo.com/video/#{data['id']}"
153
+ video.id = "#{data['uri']}".gsub(/[^\d]/, '').to_i
154
+ video.title = data['name']
155
+ video.description = data['description'] || "No description found"
156
+ video.thumbnail_url = data['pictures']['sizes'][0]['link']
157
+ video.url = data['link']
158
+ video.embed_url = "https://player.vimeo.com/video/#{video.id}"
155
159
  video.duration = data['duration'].to_i
156
- video.num_views = data['number_of_plays'].to_i
157
- video.num_likes = data['number_of_likes'].to_i
158
- video.num_comments = data['number_of_comments'].to_i
159
- video.created_date = Date.parse(data['upload_date'])
160
- video.username = data['owner']['display_name']
160
+ video.num_views = data['stats']['plays'].to_i
161
+ video.num_likes = data['metadata']['connections']['likes']['total'].to_i
162
+ video.num_comments = data['metadata']['connections']['comments']['total'].to_i
163
+ video.created_date = Date.parse(data['created_time'])
164
+ video.username = data['user']['name']
161
165
  video.width = 640
162
166
  video.height = 360
163
167
 
@@ -172,13 +176,12 @@ module ActivePublicResources
172
176
  video.return_types << APR::ReturnTypes::Iframe.new(
173
177
  :driver => DRIVER_NAME,
174
178
  :remote_id => video.id,
175
- :url => "https://player.vimeo.com/video/#{data['id']}",
179
+ :url => "https://player.vimeo.com/video/#{video.id}",
176
180
  :text => video.title,
177
181
  :title => video.title,
178
182
  :width => 640,
179
183
  :height => 360
180
184
  )
181
-
182
185
  video
183
186
  end
184
187
 
@@ -18,7 +18,7 @@ module ActivePublicResources
18
18
  def perform_request(request_criteria)
19
19
  request_criteria.set_default_criteria!(@default_request_criteria)
20
20
  unless request_criteria.validate_presence(:query) || request_criteria.validate_presence(:channel)
21
- raise ArgumentError "You must specify at least a query or channel"
21
+ raise ArgumentError, "You must specify at least a query or channel"
22
22
  end
23
23
 
24
24
  uri = URI('https://www.googleapis.com/youtube/v3/search')
@@ -110,6 +110,7 @@ module ActivePublicResources
110
110
  def next_criteria(request_criteria, results)
111
111
  if results['nextPageToken']
112
112
  return RequestCriteria.new({
113
+ channel_name: request_criteria.channel_name,
113
114
  query: request_criteria.query,
114
115
  page: results['nextPageToken'],
115
116
  per_page: results['pageInfo']['resultsPerPage'].to_i
@@ -120,25 +121,25 @@ module ActivePublicResources
120
121
  def parse_video(item)
121
122
  video_id = item['id']
122
123
  snippet = item['snippet']
123
- statistics = item['statistics']
124
+ statistics = item['statistics'] ? item['statistics'] : {}
124
125
  details = item['contentDetails']
125
126
  video = APR::ResponseTypes::Video.new
126
127
  video.id = video_id
127
128
  video.title = snippet['title']
128
129
  video.description = snippet['description']
129
130
  video.thumbnail_url = snippet['thumbnails']['default']['url']
130
- video.url = "https://www.youtube.com/watch?v=#{video_id}&feature=youtube_gdata_player"
131
- video.embed_url = "https://www.youtube.com/embed/#{video_id}?feature=oembed&rel=0"
131
+ video.url = "https://www.youtube-nocookie.com/embed/#{video_id}?feature=oembed&rel=0"
132
132
  video.duration = ISO8601::Duration.new(details['duration']).to_seconds
133
133
  video.num_views = statistics['viewCount'] ? statistics['viewCount'].to_i : 0
134
134
  video.num_likes = statistics['likeCount'] ? statistics['likeCount'].to_i : 0
135
- video.num_comments = statistics['commentCount'] ? statistics['commentCount'] : 0
135
+ video.num_comments = statistics['commentCount'] ? statistics['commentCount'].to_i : 0
136
136
  video.created_date = Date.parse(snippet['publishedAt'])
137
137
  video.username = snippet['channelTitle']
138
138
  video.width = 640
139
139
  video.height = 360
140
140
 
141
141
  # Return Types
142
+
142
143
  video.return_types << APR::ReturnTypes::Url.new(
143
144
  driver: DRIVER_NAME,
144
145
  remote_id: video.id,
@@ -146,10 +147,11 @@ module ActivePublicResources
146
147
  text: video.title,
147
148
  title: video.title
148
149
  )
150
+
149
151
  video.return_types << APR::ReturnTypes::Iframe.new(
150
152
  driver: DRIVER_NAME,
151
153
  remote_id: video.id,
152
- url: video.embed_url,
154
+ url: video.url,
153
155
  text: video.title,
154
156
  title: video.title,
155
157
  width: 640,
@@ -0,0 +1,35 @@
1
+ require 'httparty'
2
+ require 'base64'
3
+
4
+ module ActivePublicResources
5
+ module OAuth
6
+ class Vimeo
7
+ attr_reader :token
8
+
9
+ AUTHORIZE_URL = 'https://api.vimeo.com/oauth/authorize/client'
10
+ VERIFY_URL = 'https://api.vimeo.com/oauth/verify'
11
+
12
+ def initialize(consumer_key, consumer_secret)
13
+ @token = Base64.urlsafe_encode64("#{consumer_key}:#{consumer_secret}")
14
+ end
15
+
16
+ def get_access_token
17
+ response = HTTParty.post(
18
+ AUTHORIZE_URL,
19
+ body: { grant_type: 'client_credentials' },
20
+ headers: { "Authorization" => "Basic #{@token}" }
21
+ )
22
+ response['access_token']
23
+ end
24
+
25
+ def verify_token?(token)
26
+ response = HTTParty.get(
27
+ VERIFY_URL,
28
+ headers: { "Authorization" => "Bearer #{token}" }
29
+ )
30
+ response.code == 200
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -1,3 +1,3 @@
1
1
  module ActivePublicResources
2
- VERSION = "0.2.4"
2
+ VERSION = "0.2.9"
3
3
  end
@@ -3,16 +3,16 @@ require 'spec_helper'
3
3
  describe APR::Drivers::Vimeo do
4
4
 
5
5
  let(:driver) { APR::Drivers::Vimeo.new(config_data[:vimeo]) }
6
-
6
+
7
7
  describe ".initialize" do
8
- it "should throw error when intializing without proper config options" do
8
+ it "should throw error when initializing without proper config options" do
9
9
  expect {
10
10
  APR::Drivers::Vimeo.new
11
11
  }.to raise_error(ArgumentError)
12
12
  end
13
13
 
14
14
  it "should build a vimeo client on initialize" do
15
- driver.client.should be_an_instance_of(::Vimeo::Advanced::Video)
15
+ driver.client.should be_an_instance_of(APR::OAuth::Vimeo)
16
16
  end
17
17
  end
18
18
 
@@ -71,5 +71,5 @@ describe APR::Drivers::Vimeo do
71
71
  item.height.should eq(360)
72
72
  end
73
73
  end
74
-
74
+
75
75
  end
@@ -1,4 +1,7 @@
1
1
  require 'spec_helper'
2
+ require 'webmock/rspec'
3
+
4
+ WebMock.disable_net_connect!
2
5
 
3
6
  describe APR::Drivers::Youtube do
4
7
 
@@ -8,45 +11,41 @@ describe APR::Drivers::Youtube do
8
11
  it "should raise error when perform_request method is called without a query" do
9
12
  expect {
10
13
  driver.perform_request(APR::RequestCriteria.new)
11
- }.to raise_error(StandardError, "must include query")
14
+ }.to raise_error(StandardError, "You must specify at least a query or channel")
12
15
  end
13
16
 
14
- it "should perform request", :vcr, :record => :none do
17
+ it "should perform request" do
18
+ stub_request(:get, "https://www.googleapis.com/youtube/v3/search?key=AIzaSyC-PDO3YHSXgfYkng3JjWp5G_HeNgJxkKM&maxResults=25&order=relevance&part=snippet&q=education&safeSearch=strict&type=video").
19
+ to_return(body: File.read('./active_public_resources/spec/lib/fixtures/youtube/education_search.json'), status: 200)
20
+ stub_request(:get, "https://www.googleapis.com/youtube/v3/videos?id=N6oIhdTzx9Q,HndV87XpkWg,S294zRodS_4,BnC6IABJXOI,xhN5Zkm82DA,8ZV_i37wxX8,nA1Aqp0sPQo,7CBKCG7HXjI,DdNAUJWJN08,imHfNDpBlCE,iG9CE55wbtY,_aB9Tg6SRA0,2lmv6ZDm0vw,nHHFGo161Os,Dvhuesh0D5s,Ky7H4CGPbvY,y_ZmM7zPLyI,CWmCrQVFujk,Cv6f-2Wlsxg,tOnDiuL2JmQ,qn9IMe5jmf0,dqTTojTija8,MhS6oqwwOhw,35VgsgICsjo,aV6w-zoacYk&key=AIzaSyC-PDO3YHSXgfYkng3JjWp5G_HeNgJxkKM&part=snippet,contentDetails,statistics").
21
+ to_return(body: File.read('./active_public_resources/spec/lib/fixtures/youtube/education_details_search.json'), status: 200)
15
22
  search_criteria = APR::RequestCriteria.new({:query => "education"})
16
23
  results = driver.perform_request(search_criteria)
17
24
  next_criteria = results.next_criteria
18
- next_criteria.page.should eq(26)
25
+ next_criteria.page.should eq('CBkQAA')
19
26
  next_criteria.per_page.should eq(25)
20
27
  results.total_items.should eq(1000000)
21
28
  results.items.length.should eq(25)
22
29
 
23
30
  item = results.items.first
24
31
  item.kind.should eq("video")
25
- item.title.should eq("Why I Hate School But Love Education||Spoken Word")
26
- item.description.should match /The Latest Spoken Word/
27
- item.thumbnail_url.should eq("https://i.ytimg.com/vi/y_ZmM7zPLyI/default.jpg")
28
- item.url.should eq("https://www.youtube.com/watch?v=y_ZmM7zPLyI&feature=youtube_gdata_player")
29
- item.duration.should eq(368)
30
- item.num_views.should eq(4228173)
31
- item.num_likes.should eq(101737)
32
- item.num_comments.should eq(17837)
33
- item.created_date.strftime("%Y-%m-%d").should eq("2012-12-02")
34
- item.username.should eq("sulibreezy")
35
- item.return_types.count.should eq(2)
36
-
37
- rt_url = item.return_types[0]
38
- rt_url.driver.should eq(APR::Drivers::Youtube::DRIVER_NAME)
39
- rt_url.remote_id.should eq("y_ZmM7zPLyI")
40
- rt_url.return_type.should eq('url')
41
- rt_url.url.should eq("https://www.youtube.com/watch?v=y_ZmM7zPLyI&feature=youtube_gdata_player")
42
- rt_url.title.should eq("Why I Hate School But Love Education||Spoken Word")
43
-
44
- rt_iframe = item.return_types[1]
32
+ item.title.should eq("10 Ways to Get a Better EDUCATION")
33
+ item.description.should match /10 Ways to Get a Better EDUCATION/
34
+ item.thumbnail_url.should eq("https://i.ytimg.com/vi/N6oIhdTzx9Q/default.jpg")
35
+ item.url.should eq("https://www.youtube-nocookie.com/embed/N6oIhdTzx9Q?feature=oembed&rel=0")
36
+ item.duration.should eq(607.0)
37
+ item.num_views.should eq(22650)
38
+ item.num_likes.should eq(1576)
39
+ item.num_comments.should eq(175)
40
+ item.created_date.strftime("%Y-%m-%d").should eq("2020-04-28")
41
+ item.username.should eq("Alux.com")
42
+ item.return_types.count.should eq(1)
43
+
44
+ rt_iframe = item.return_types[0]
45
45
  rt_iframe.driver.should eq(APR::Drivers::Youtube::DRIVER_NAME)
46
- rt_iframe.remote_id.should eq("y_ZmM7zPLyI")
46
+ rt_iframe.remote_id.should eq("N6oIhdTzx9Q")
47
47
  rt_iframe.return_type.should eq('iframe')
48
- rt_iframe.url.should eq("https://www.youtube.com/embed/y_ZmM7zPLyI?feature=oembed")
49
- rt_url.title.should eq("Why I Hate School But Love Education||Spoken Word")
48
+ rt_iframe.url.should eq("https://www.youtube-nocookie.com/embed/N6oIhdTzx9Q?feature=oembed&rel=0")
50
49
 
51
50
  item.width.should eq(640)
52
51
  item.height.should eq(360)
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+ require 'base64'
3
+ require 'securerandom'
4
+
5
+ describe APR::OAuth::Vimeo do
6
+
7
+ let(:client) { APR::OAuth::Vimeo.new(consumer_key, consumer_secret) }
8
+ let(:consumer_key) { 'key' }
9
+ let(:consumer_secret) { 'secret' }
10
+ let(:token) { Base64.urlsafe_encode64("#{consumer_key}:#{consumer_secret}") }
11
+ let(:access_token) { "#{SecureRandom.uuid}" }
12
+
13
+ describe ".initialize" do
14
+ it "should build a base64 encoded token" do
15
+ expect(client.token).to eq token
16
+ end
17
+ end
18
+
19
+ describe "#get_access_token" do
20
+ let(:response) { { "access_token" => access_token } }
21
+
22
+ it "should generate an access token" do
23
+ allow(HTTParty).to receive(:post) { response }
24
+ expect(client.get_access_token).to eq access_token
25
+ end
26
+ end
27
+
28
+ describe "#verify_token?" do
29
+ let(:response_ok) { double(:code => 200) }
30
+ let(:response_unauthorized) { double(:code => 401) }
31
+
32
+ it "should return 200 if token is verified" do
33
+ allow(HTTParty).to receive(:get) { response_ok }
34
+ expect(client.verify_token?(token)).to eq true
35
+ end
36
+
37
+ it "should return 401 if token is unauthorized" do
38
+ allow(HTTParty).to receive(:get) { response_unauthorized }
39
+ expect(client.verify_token?(token)).to eq false
40
+ end
41
+ end
42
+
43
+ end