john_stamos 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +95 -79
- data/john_stamos.gemspec +3 -2
- data/lib/john_stamos/client.rb +32 -17
- data/lib/john_stamos/pin_search.rb +4 -3
- data/lib/john_stamos/pinner.rb +1 -1
- data/lib/john_stamos/version.rb +1 -1
- data/lib/john_stamos.rb +5 -2
- data/spec/lib/john_stamos/client_spec.rb +55 -66
- data/spec/lib/john_stamos/pin_search_spec.rb +9 -9
- data/spec/support/vcr_cassettes/JohnStamos_Client/_make_request/returns_a_string_representation_of_the_response_body.yml +59 -0
- data/spec/support/vcr_cassettes/JohnStamos_Client/_page_content/returns_a_Nokogiri_HTML_Document_object.yml +59 -0
- data/spec/support/vcr_cassettes/JohnStamos_Client/_search_pins/returns_the_correct_number_of_pins.yml +6448 -980
- data/spec/support/vcr_cassettes/JohnStamos_Pin/scraped_data/_pinner/returns_a_Pinner_object.yml +801 -289
- data/spec/support/vcr_cassettes/JohnStamos_Pin/scraped_data/_pinner/shows_my_fake_account_as_the_owning_Pinner.yml +802 -289
- data/spec/support/vcr_cassettes/JohnStamos_Pin/scraped_data/belongs_to_the_correct_board.yml +801 -289
- data/spec/support/vcr_cassettes/JohnStamos_Pin/scraped_data/has_the_correct_description.yml +801 -289
- data/spec/support/vcr_cassettes/JohnStamos_Pin/scraped_data/has_the_correct_image.yml +801 -289
- data/spec/support/vcr_cassettes/JohnStamos_Pin/scraped_data/has_the_correct_like_count.yml +1329 -287
- data/spec/support/vcr_cassettes/JohnStamos_Pin/scraped_data/has_the_correct_repin_count.yml +801 -289
- data/spec/support/vcr_cassettes/JohnStamos_Pin/scraped_data/has_the_correct_source_url.yml +801 -290
- data/spec/support/vcr_cassettes/JohnStamos_Pin/scraped_data/is_not_a_video.yml +801 -289
- data/spec/support/vcr_cassettes/JohnStamos_PinSearch/_execute_/when_using_a_search_term_that_yields_thousands_of_pins/with_a_limit_higher_than_the_default/collects_the_correct_number_of_pin_ids.yml +16392 -2609
- data/spec/support/vcr_cassettes/JohnStamos_PinSearch/_execute_/when_using_a_search_term_that_yields_thousands_of_pins/with_a_limit_lower_than_the_default/collects_the_correct_number_of_pin_ids.yml +10844 -1157
- data/spec/support/vcr_cassettes/JohnStamos_PinSearch/_execute_/when_using_a_search_term_that_yields_thousands_of_pins/with_a_limit_lower_than_the_default/never_calls_subsequent_retrieval_.yml +10844 -1157
- data/spec/support/vcr_cassettes/JohnStamos_PinSearch/_execute_/when_using_a_search_term_that_yields_thousands_of_pins/with_no_limit_specified/limits_the_pin_ids_collected_to_50.yml +10844 -1655
- data/spec/support/vcr_cassettes/JohnStamos_PinSearch/_execute_/when_using_a_search_term_that_yields_thousands_of_pins/with_no_limit_specified/limits_to_50_the_default.yml +10844 -1655
- data/spec/support/vcr_cassettes/JohnStamos_PinSearch/_first_retrieval_/with_results_found/sets_next_bookmark.yml +5128 -993
- data/spec/support/vcr_cassettes/JohnStamos_PinSearch/_first_retrieval_/with_results_found/sets_next_bookmark_with_a_hash_for_the_next_25_results.yml +5170 -0
- data/spec/support/vcr_cassettes/JohnStamos_PinSearch/_first_retrieval_/with_results_found/sets_next_bookmark_with_a_hash_for_the_next_batch_of_results.yml +5170 -0
- data/spec/support/vcr_cassettes/JohnStamos_PinSearch/_first_retrieval_/with_results_found/should_set_pin_ids.yml +5128 -993
- data/spec/support/vcr_cassettes/JohnStamos_PinSearch/_first_retrieval_/without_any_results_found/has_a_nil_next_bookmark.yml +834 -211
- data/spec/support/vcr_cassettes/JohnStamos_PinSearch/_first_retrieval_/without_any_results_found/leaves_the_pin_ids_array_empty.yml +834 -212
- data/spec/support/vcr_cassettes/JohnStamos_PinSearch/_subsequent_retrieval/with_results_found/sets_next_bookmark_with_a_hash_for_the_next_25_results.yml +9053 -0
- data/spec/support/vcr_cassettes/JohnStamos_PinSearch/_subsequent_retrieval/with_results_found/sets_next_bookmark_with_a_hash_for_the_next_batch_of_results.yml +9053 -0
- data/spec/support/vcr_cassettes/JohnStamos_PinSearch/_subsequent_retrieval/with_results_found/sets_the_next_bookmark.yml +8972 -1691
- data/spec/support/vcr_cassettes/JohnStamos_PinSearch/_subsequent_retrieval/with_results_found/should_append_the_new_pin_ids.yml +8972 -1691
- data/spec/support/vcr_cassettes/JohnStamos_Pinner/_about/returns_the_correct_about_text.yml +639 -247
- data/spec/support/vcr_cassettes/JohnStamos_Pinner/_avatar/returns_the_correct_avatar_URL.yml +639 -246
- data/spec/support/vcr_cassettes/JohnStamos_Pinner/_board_count/returns_the_correct_number_of_boards.yml +639 -246
- data/spec/support/vcr_cassettes/JohnStamos_Pinner/_follower_count/returns_a_follower_count_of_0.yml +639 -246
- data/spec/support/vcr_cassettes/JohnStamos_Pinner/_location/returns_the_correct_location.yml +639 -247
- data/spec/support/vcr_cassettes/JohnStamos_Pinner/_pin_count/returns_the_correct_number_of_pins.yml +639 -246
- data/spec/support/vcr_cassettes/JohnStamos_Pinner/_website_url/returns_the_correct_website_url.yml +639 -246
- data/spec/support/vcr_cassettes/JohnStamos_Pinner/name_related_attributes/returns_the_correct_first_name.yml +1039 -244
- data/spec/support/vcr_cassettes/JohnStamos_Pinner/name_related_attributes/returns_the_correct_full_name.yml +639 -246
- data/spec/support/vcr_cassettes/JohnStamos_Pinner/name_related_attributes/returns_the_correct_last_name.yml +639 -246
- metadata +163 -146
- checksums.yaml +0 -7
- data/spec/support/vcr_cassettes/JohnStamos_Client/_page_content/returns_a_Mechanize_Page.yml +0 -221
- data/spec/support/vcr_cassettes/JohnStamos_PinSearch/_first_retrieval_/with_results_found/sets_next_bookmark_with_a_hash_for_the_next_50_results.yml +0 -1035
- data/spec/support/vcr_cassettes/JohnStamos_PinSearch/_subsequent_retrieval/with_results_found/sets_next_bookmark_with_a_hash_for_the_next_50_results.yml +0 -1772
data/README.md
CHANGED
@@ -1,26 +1,35 @@
|
|
1
|
-
# JohnStamos
|
1
|
+
# JohnStamos
|
2
2
|
|
3
3
|
The greasiest Pinterest client. JohnStamos exposes an interface you can use to query Pinterest for data about individual Pins, Pinners and Pin searches. Have mercy.
|
4
4
|
|
5
5
|
[![Build Status](https://travis-ci.org/mariozig/john_stamos.png?branch=master)](https://travis-ci.org/mariozig/john_stamos)
|
6
|
+
[![Code Climate](https://codeclimate.com/github/mariozig/john_stamos.png)](https://codeclimate.com/github/mariozig/john_stamos)
|
6
7
|
|
7
8
|
## Installation
|
8
9
|
|
9
10
|
Add this line to your application's Gemfile:
|
10
11
|
|
11
|
-
|
12
|
+
```
|
13
|
+
gem 'john_stamos'
|
14
|
+
```
|
12
15
|
|
13
16
|
And then execute:
|
14
17
|
|
15
|
-
|
18
|
+
```
|
19
|
+
$ bundle
|
20
|
+
```
|
16
21
|
|
17
22
|
Or install it yourself as:
|
18
23
|
|
19
|
-
|
24
|
+
```
|
25
|
+
$ gem install john_stamos
|
26
|
+
```
|
20
27
|
|
21
28
|
Or finally, if none of that stuff applies to you, do what it takes to install the gem and add this to your script:
|
22
29
|
|
23
|
-
|
30
|
+
```ruby
|
31
|
+
require 'john_stamos'
|
32
|
+
```
|
24
33
|
|
25
34
|
## Usage
|
26
35
|
|
@@ -28,95 +37,102 @@ Or finally, if none of that stuff applies to you, do what it takes to install th
|
|
28
37
|
|
29
38
|
Here's a typical use-case: You want to search Pinterest for some pins. Once you have those pins, you want to access information about each individual pin as well as information about the person who pinned it.
|
30
39
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
40
|
+
```ruby
|
41
|
+
client = JohnStamos::Client.new
|
42
|
+
|
43
|
+
# Search for some sweet Pins of "pallet gardens"
|
44
|
+
pins = client.search_pins("pallet gardens", limit: 10)
|
45
|
+
# Returns an Array of Pin objects
|
46
|
+
|
47
|
+
# The first Pin will be fun to investigate.
|
48
|
+
first_pallet_garden_pin = pallet_search.first
|
49
|
+
|
50
|
+
# Print some info about the first Pin description
|
51
|
+
puts first_pallet_garden_pin.description
|
52
|
+
# => "A cool pallet garden"
|
53
|
+
|
54
|
+
# the full sized image
|
55
|
+
puts first_pallet_garden_pin.image
|
56
|
+
# => "http://media-cache-ak0.pinimg.com/originals....whatever.jpg"
|
57
|
+
|
58
|
+
# Pinterest's ID for this Pin
|
59
|
+
puts first_pallet_garden_pin.id
|
60
|
+
# => "123456789"
|
61
|
+
|
62
|
+
# URL to the Pin
|
63
|
+
puts first_pallet_garden_pin.url
|
64
|
+
# => "http://pinterest.com/pin/123456789"
|
65
|
+
|
66
|
+
# We can even get at the user who Pinned this Pin
|
67
|
+
first_pallet_garden_pin.pinner
|
68
|
+
|
69
|
+
# Print the Pinner's full name
|
70
|
+
puts first_pallet_garden_pin.pinner.full_name
|
71
|
+
# => "Little Bobby Tables"
|
72
|
+
```
|
62
73
|
|
63
74
|
### Using the Client
|
64
75
|
|
65
|
-
The Client is the single entry point into all things JohnStamos.
|
76
|
+
The Client is the single entry point into all things JohnStamos.
|
66
77
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
# The Client also supports using a proxy
|
71
|
-
client_with_proxy = JohnStamos::Client.new(proxy: 'http://127.1.1.1:4747')
|
72
|
-
|
73
|
-
# Note: If you're hosted on Heroku, you will want to use a proxy.
|
78
|
+
```ruby
|
79
|
+
# Create a new Client
|
80
|
+
client = JohnStamos::Client.new
|
74
81
|
|
82
|
+
# The Client also supports using a proxy
|
83
|
+
client_with_proxy = JohnStamos::Client.new(proxy: 'http://127.1.1.1:4747')
|
84
|
+
|
85
|
+
# Note: If you're hosted on Heroku, you will want to use a proxy.
|
86
|
+
```
|
75
87
|
|
76
88
|
### Accessing Individual Pin Data
|
77
89
|
|
78
90
|
There are times you might want to access an individual Pin's information. All you need is the ID assigned to the Pin by Pinterest to get going.
|
79
91
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
92
|
+
```ruby
|
93
|
+
client = JohnStamos::Client.new
|
94
|
+
|
95
|
+
# Get a magnificent Pin using it's ID
|
96
|
+
perfect_strangers_pin = client.pin(161848180328631541)
|
97
|
+
|
98
|
+
puts perfect_strangers_pin.description
|
99
|
+
# => "Balki Bartokomous and Cousin Larry!!! PERFECT STRANGERS...loved that show!"
|
100
|
+
|
101
|
+
puts perfect_strangers_pin.image
|
102
|
+
# => "http://media-cache-ec0.pinimg.com/originals/4b/10/d3/4b10d3bd1c172c52934eb2d79ff0031f.jpg"
|
103
|
+
|
104
|
+
# If you didn't look at that image above, please do it before reading further
|
105
|
+
|
106
|
+
puts perfect_strangers_pin.url
|
107
|
+
# => "http://pinterest.com/pin/161848180328631541/"
|
108
|
+
|
109
|
+
puts perfect_strangers_pin.repin_count
|
110
|
+
# => 1
|
111
|
+
```
|
98
112
|
|
99
113
|
### Accessing Pinner Data
|
100
114
|
|
101
115
|
You can also query Pinterest for information about specific Pinners. Just pass in the Pinner's user name and you will be good to go.
|
102
116
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
117
|
+
```ruby
|
118
|
+
client = JohnStamos::Client.new
|
119
|
+
|
120
|
+
# Get Michelle Obama's account
|
121
|
+
michelle_obama = client.pinner("michelleobama")
|
122
|
+
|
123
|
+
# Print some of the Pinner's information
|
124
|
+
puts michelle_obama.last_name
|
125
|
+
# => "Obama"
|
126
|
+
|
127
|
+
puts michelle_obama.first_name
|
128
|
+
# => "Michelle"
|
129
|
+
|
130
|
+
puts michelle_obama.pin_count
|
131
|
+
# => "81"
|
132
|
+
|
133
|
+
puts michelle_obama.website_url
|
134
|
+
# => "http://www.barackobama.com"
|
135
|
+
```
|
120
136
|
|
121
137
|
## Contributing
|
122
138
|
|
data/john_stamos.gemspec
CHANGED
@@ -25,8 +25,9 @@ Gem::Specification.new do |gem|
|
|
25
25
|
gem.add_development_dependency "vcr"
|
26
26
|
gem.add_development_dependency "guard-rspec"
|
27
27
|
|
28
|
-
gem.add_dependency "
|
29
|
-
gem.add_dependency "
|
28
|
+
gem.add_dependency "nokogiri"
|
29
|
+
gem.add_dependency "faraday"
|
30
|
+
gem.add_dependency "typhoeus"
|
30
31
|
gem.add_dependency "json"
|
31
32
|
gem.add_dependency "launchy"
|
32
33
|
end
|
data/lib/john_stamos/client.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
1
3
|
class JohnStamos::Client
|
2
4
|
attr_accessor :proxy
|
3
5
|
|
@@ -23,35 +25,48 @@ class JohnStamos::Client
|
|
23
25
|
end
|
24
26
|
|
25
27
|
def page_content(url)
|
26
|
-
|
27
|
-
page = mechanize_agent.get(url)
|
28
|
-
rescue Mechanize::ResponseReadError => e
|
29
|
-
$stderr.puts "#{e.class}: #{e.message}"
|
30
|
-
$stderr.puts "An error occured; attempting to force_parse"
|
31
|
-
page = e.force_parse
|
32
|
-
end
|
28
|
+
response = make_request(url)
|
33
29
|
|
34
|
-
|
30
|
+
Nokogiri::HTML(response)
|
35
31
|
end
|
36
32
|
|
37
33
|
def json_content(url, params)
|
38
|
-
|
39
|
-
response = RestClient.get(url, params: params, accept: :json, "X-Requested-With" => "XMLHttpRequest")
|
34
|
+
response = make_json_request(url, params)
|
40
35
|
|
41
36
|
JSON.parse(response)
|
42
37
|
end
|
43
38
|
|
44
39
|
private
|
45
|
-
def
|
46
|
-
|
47
|
-
agent.user_agent_alias = 'Mac Safari'
|
40
|
+
def make_request(url, params={}, accept_json=false)
|
41
|
+
request_headers = build_request_headers(accept_json)
|
48
42
|
|
49
|
-
|
50
|
-
|
51
|
-
|
43
|
+
response = pinterest_connection.get do |req|
|
44
|
+
req.url url, params
|
45
|
+
req.headers = request_headers
|
52
46
|
end
|
53
47
|
|
54
|
-
|
48
|
+
response.body
|
49
|
+
end
|
50
|
+
|
51
|
+
def make_json_request(url, params={})
|
52
|
+
make_request(url, params, true)
|
53
|
+
end
|
54
|
+
|
55
|
+
def build_request_headers(accept_json=false)
|
56
|
+
headers = {}
|
57
|
+
|
58
|
+
if accept_json
|
59
|
+
headers['Accept'] = 'application/json'
|
60
|
+
headers['X-Requested-With'] = 'XMLHttpRequest'
|
61
|
+
end
|
62
|
+
headers['User-Agent'] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36'
|
63
|
+
|
64
|
+
headers
|
65
|
+
end
|
66
|
+
|
67
|
+
def pinterest_connection
|
68
|
+
pinterest_url = 'http://pinterest.com'
|
69
|
+
@pinterest_connection ||= @proxy.nil? ? Faraday.new(url: pinterest_url) : Faraday.new(url: pinterest_url, proxy: @proxy)
|
55
70
|
end
|
56
71
|
|
57
72
|
end
|
@@ -25,11 +25,11 @@ class JohnStamos::PinSearch
|
|
25
25
|
|
26
26
|
def first_retrieval_url
|
27
27
|
raise JohnStamos::MissingSearchText if @search_text.nil?
|
28
|
-
"
|
28
|
+
"/search/pins/?q=#{URI::encode(@search_text)}"
|
29
29
|
end
|
30
30
|
|
31
31
|
def subsequent_retrieval_url
|
32
|
-
'
|
32
|
+
'/resource/SearchResource/get/'
|
33
33
|
end
|
34
34
|
|
35
35
|
def first_retrieval!
|
@@ -134,7 +134,8 @@ class JohnStamos::PinSearch
|
|
134
134
|
|
135
135
|
url_params = {
|
136
136
|
source_url: "/search/pins/?q=#{URI::encode(search_text)}",
|
137
|
-
|
137
|
+
# Pass in the current time in miliseconds (like pinterest does) to prevent caching
|
138
|
+
"_" => (Time.now.to_f * 1000.0).to_i,
|
138
139
|
data: data_json.to_json
|
139
140
|
}
|
140
141
|
url_params
|
data/lib/john_stamos/pinner.rb
CHANGED
data/lib/john_stamos/version.rb
CHANGED
data/lib/john_stamos.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
-
require '
|
1
|
+
require 'faraday'
|
2
|
+
require 'typhoeus/adapters/faraday'
|
3
|
+
require 'nokogiri'
|
2
4
|
require 'json'
|
3
|
-
require 'rest_client'
|
4
5
|
require 'launchy'
|
5
6
|
|
6
7
|
require 'john_stamos/version'
|
@@ -13,6 +14,8 @@ module JohnStamos
|
|
13
14
|
class MissingSearchText < Exception; end
|
14
15
|
class MissingNextBookmark < Exception; end
|
15
16
|
|
17
|
+
Faraday.default_adapter = :typhoeus
|
18
|
+
|
16
19
|
private
|
17
20
|
def self.uncle_jesse
|
18
21
|
Launchy.open('http://www.youtube.com/watch?v=bLqAqIj8Rdc')
|
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe JohnStamos::Client, :vcr do
|
4
4
|
subject(:client) { JohnStamos::Client.new }
|
5
|
-
let(:pinterest_url) { '
|
5
|
+
let(:pinterest_url) { 'http://pinterest.com' }
|
6
6
|
|
7
7
|
describe '#search_pins' do
|
8
8
|
it 'responds to #search_pins' do
|
@@ -49,99 +49,88 @@ describe JohnStamos::Client, :vcr do
|
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
|
-
describe '#
|
53
|
-
it 'responds to #
|
54
|
-
expect(client).to respond_to(:
|
52
|
+
describe '#page_content' do
|
53
|
+
it 'responds to #page_content' do
|
54
|
+
expect(client).to respond_to(:page_content)
|
55
55
|
end
|
56
56
|
|
57
|
-
it 'returns a
|
58
|
-
|
59
|
-
|
60
|
-
expect(client.json_content('url', 'params')).to be_a(Hash)
|
57
|
+
it 'returns a Nokogiri::HTML::Document object' do
|
58
|
+
expect(client.page_content(pinterest_url)).to be_a(Nokogiri::HTML::Document)
|
61
59
|
end
|
62
60
|
end
|
63
61
|
|
64
|
-
describe '#
|
65
|
-
let(:
|
66
|
-
|
67
|
-
context 'when using a proxy' do
|
68
|
-
before(:each) do
|
69
|
-
client.proxy = 'http://proxy.com:4747'
|
70
|
-
end
|
71
|
-
|
72
|
-
it 'sets the correct hostname' do
|
73
|
-
expect(agent.proxy_addr).to eq('proxy.com')
|
74
|
-
end
|
62
|
+
describe '#json_content' do
|
63
|
+
let(:fake_json) { '{ "key":"value" }' }
|
75
64
|
|
76
|
-
|
77
|
-
|
78
|
-
end
|
65
|
+
it 'responds to #json_content' do
|
66
|
+
expect(client).to respond_to(:json_content)
|
79
67
|
end
|
80
68
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
end
|
85
|
-
|
86
|
-
it 'does not set a hostname' do
|
87
|
-
expect(agent.proxy_addr).to be_nil
|
88
|
-
end
|
89
|
-
|
90
|
-
it 'does not set a port' do
|
91
|
-
expect(agent.proxy_port).to be_nil
|
92
|
-
end
|
69
|
+
it 'returns a Hash representation of the JSON' do
|
70
|
+
client.stub(:make_request).and_return(fake_json)
|
71
|
+
expect(client.json_content(nil, nil)).to be_a(Hash)
|
93
72
|
end
|
94
73
|
end
|
95
74
|
|
96
|
-
describe '#
|
97
|
-
it '
|
98
|
-
|
75
|
+
describe '#make_request' do
|
76
|
+
it 'returns a string representation of the response body' do
|
77
|
+
response = client.send(:make_request, pinterest_url, {})
|
78
|
+
expect(response).to be_a(String)
|
99
79
|
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe '#make_json_request' do
|
83
|
+
it 'calls #make_request with the correct params' do
|
84
|
+
client.stub(:make_request).and_return(nil)
|
85
|
+
expect(client).to receive(:make_request).with('a', 'b', true)
|
100
86
|
|
101
|
-
|
102
|
-
expect(client.page_content(pinterest_url)).to be_a(Mechanize::Page)
|
87
|
+
client.send(:make_json_request, 'a', 'b')
|
103
88
|
end
|
104
89
|
end
|
105
90
|
|
106
|
-
describe '#
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
91
|
+
describe '#pinterest_connection' do
|
92
|
+
context 'when using a proxy' do
|
93
|
+
it 'creates a new Faraday proxied instance' do
|
94
|
+
client.proxy = 'http://fakeproxy.com:1234'
|
95
|
+
expect(Faraday).to receive(:new).with({ url: pinterest_url, proxy: client.proxy })
|
96
|
+
client.send(:pinterest_connection)
|
97
|
+
end
|
111
98
|
end
|
112
99
|
|
113
100
|
context 'when not using a proxy' do
|
114
|
-
|
115
|
-
|
101
|
+
it 'creates a new Faraday instance' do
|
102
|
+
client.proxy = nil
|
103
|
+
expect(Faraday).to receive(:new).with({ url: pinterest_url })
|
104
|
+
client.send(:pinterest_connection)
|
116
105
|
end
|
106
|
+
end
|
107
|
+
end
|
117
108
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
109
|
+
describe '#build_request_headers' do
|
110
|
+
it 'has a valid User-Agent' do
|
111
|
+
headers = client.send(:build_request_headers)
|
112
|
+
expect(headers['User-Agent']).to eq('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36')
|
113
|
+
end
|
123
114
|
|
124
|
-
|
125
|
-
|
126
|
-
|
115
|
+
context 'non-JSON requests' do
|
116
|
+
it 'do not contain JSON request related headers' do
|
117
|
+
headers = client.send(:build_request_headers)
|
118
|
+
expect(headers).not_to include('Accept', 'X-Requested-With')
|
127
119
|
end
|
128
120
|
end
|
129
121
|
|
130
|
-
context '
|
131
|
-
let(:
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
allow(RestClient).to receive(:get).and_return(fake_json)
|
122
|
+
context 'JSON requests' do
|
123
|
+
let(:json_headers) do
|
124
|
+
headers = {}
|
125
|
+
headers['Accept'] = 'application/json'
|
126
|
+
headers['X-Requested-With'] = 'XMLHttpRequest'
|
127
|
+
headers
|
137
128
|
end
|
138
129
|
|
139
|
-
it '
|
140
|
-
|
141
|
-
expect(
|
130
|
+
it 'contain JSON request related headers' do
|
131
|
+
headers = client.send(:build_request_headers, true)
|
132
|
+
expect(headers).to include(json_headers)
|
142
133
|
end
|
143
134
|
end
|
144
|
-
|
145
|
-
|
146
135
|
end
|
147
136
|
end
|
@@ -89,7 +89,7 @@ describe JohnStamos::PinSearch, :vcr do
|
|
89
89
|
|
90
90
|
it 'returns the correct URL with the search text URL encoded' do
|
91
91
|
scraper.search_text = search_text
|
92
|
-
expect(scraper.first_retrieval_url).to eq('
|
92
|
+
expect(scraper.first_retrieval_url).to eq('/search/pins/?q=coffee%20roasting')
|
93
93
|
end
|
94
94
|
end
|
95
95
|
|
@@ -102,15 +102,15 @@ describe JohnStamos::PinSearch, :vcr do
|
|
102
102
|
expect { scraper.first_retrieval! }.to change{ scraper.next_bookmark }.from(nil)
|
103
103
|
end
|
104
104
|
|
105
|
-
it 'sets next_bookmark with a hash for the next
|
105
|
+
it 'sets next_bookmark with a hash for the next batch of results' do
|
106
106
|
scraper.first_retrieval!
|
107
107
|
decrypted_hash = Base64.strict_decode64(scraper.next_bookmark)
|
108
108
|
next_page_results_start_position = decrypted_hash.split('|')[0]
|
109
|
-
next_page_results_start_position.should eq("
|
109
|
+
next_page_results_start_position.should eq("oo25")
|
110
110
|
end
|
111
111
|
|
112
112
|
it 'should set pin_ids' do
|
113
|
-
expect { scraper.first_retrieval! }.to change{ scraper.pin_ids.length }.from(0).to(
|
113
|
+
expect { scraper.first_retrieval! }.to change{ scraper.pin_ids.length }.from(0).to(25)
|
114
114
|
end
|
115
115
|
end
|
116
116
|
|
@@ -133,7 +133,7 @@ describe JohnStamos::PinSearch, :vcr do
|
|
133
133
|
|
134
134
|
describe '#subsequent_retrieval_url' do
|
135
135
|
it 'returns the correct "resource" url' do
|
136
|
-
expect(scraper.subsequent_retrieval_url).to eq('
|
136
|
+
expect(scraper.subsequent_retrieval_url).to eq('/resource/SearchResource/get/')
|
137
137
|
end
|
138
138
|
end
|
139
139
|
|
@@ -163,18 +163,18 @@ describe JohnStamos::PinSearch, :vcr do
|
|
163
163
|
expect { scraper.subsequent_retrieval! }.to change{ scraper.next_bookmark }
|
164
164
|
end
|
165
165
|
|
166
|
-
it 'sets next_bookmark with a hash for the next
|
166
|
+
it 'sets next_bookmark with a hash for the next batch of results' do
|
167
167
|
scraper.subsequent_retrieval!
|
168
168
|
decrypted_hash = Base64.strict_decode64(scraper.next_bookmark)
|
169
169
|
next_page_results_start_position = decrypted_hash.split('|')[0]
|
170
|
-
expect(next_page_results_start_position).to eq("
|
170
|
+
expect(next_page_results_start_position).to eq("oo50")
|
171
171
|
end
|
172
172
|
|
173
173
|
it 'should append the new pin_ids' do
|
174
|
-
# The expected count can change based on Pinterest. Sometimes they give
|
174
|
+
# The expected count can change based on Pinterest. Sometimes they give 1 less than expected.
|
175
175
|
# When you update the VCR cassettes it may cause this test to fail... please update it.
|
176
176
|
scraper.subsequent_retrieval!
|
177
|
-
expect(scraper.pin_ids.length).to eq(
|
177
|
+
expect(scraper.pin_ids.length).to eq(50)
|
178
178
|
end
|
179
179
|
end
|
180
180
|
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: http://pinterest.com/
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers:
|
10
|
+
User-Agent:
|
11
|
+
- Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML,
|
12
|
+
like Gecko) Chrome/28.0.1500.95 Safari/537.36
|
13
|
+
response:
|
14
|
+
status:
|
15
|
+
code: 302
|
16
|
+
message: FOUND
|
17
|
+
headers:
|
18
|
+
Accept-Ranges:
|
19
|
+
- bytes
|
20
|
+
Age:
|
21
|
+
- '0'
|
22
|
+
Cache-Control:
|
23
|
+
- no-cache
|
24
|
+
Content-Type:
|
25
|
+
- text/html; charset=utf-8
|
26
|
+
Date:
|
27
|
+
- Thu, 22 Aug 2013 23:38:02 GMT
|
28
|
+
Location:
|
29
|
+
- https://pinterest.com/
|
30
|
+
Pinterest-Breed:
|
31
|
+
- CORGI
|
32
|
+
Pinterest-Generated-By:
|
33
|
+
- ngapp-1b3b34b2
|
34
|
+
Pinterest-Version:
|
35
|
+
- 5bdef68
|
36
|
+
Server:
|
37
|
+
- nginx
|
38
|
+
Set-Cookie:
|
39
|
+
- _pinterest_sess="eJzzNvE19PDKjbKoSql0NTLwCApxTPZPystO8yi3tY8vycxNtfUN8TX2q/Ks8HOJNPFNt7VVK04tLs5MsfXM8jSODMk28HPxyvY1iqzwCwk0jQyJNPXNSq/ydwnKisoNrfDL8gLSYTmeQH0AYikjhQ==";
|
40
|
+
Domain=.pinterest.com; expires=Sun, 17-Aug-2014 23:38:02 GMT; Max-Age=31103999;
|
41
|
+
Path=/
|
42
|
+
- csrftoken=3pu9GXdpS9N8ilNUApaOtopW0nV0tOOn; Domain=.pinterest.com; expires=Thu,
|
43
|
+
21-Aug-2014 23:38:02 GMT; Max-Age=31449600; Path=/
|
44
|
+
Vary:
|
45
|
+
- Cookie
|
46
|
+
Via:
|
47
|
+
- 1.1 varnish
|
48
|
+
X-Varnish:
|
49
|
+
- '2111788339'
|
50
|
+
Content-Length:
|
51
|
+
- '0'
|
52
|
+
Connection:
|
53
|
+
- keep-alive
|
54
|
+
body:
|
55
|
+
encoding: UTF-8
|
56
|
+
string: ''
|
57
|
+
http_version:
|
58
|
+
recorded_at: Thu, 22 Aug 2013 23:38:02 GMT
|
59
|
+
recorded_with: VCR 2.5.0
|