redvine 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +22 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +45 -0
- data/Rakefile +1 -0
- data/config.yml_TEMPLATE +2 -0
- data/lib/redvine.rb +67 -0
- data/lib/redvine/version.rb +3 -0
- data/redvine.gemspec +27 -0
- data/spec/redvine_spec.rb +169 -0
- data/spec/spec_helper.rb +13 -0
- data/spec/vcr_setup.rb +6 -0
- metadata +156 -0
data/.gitignore
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
|
19
|
+
/.rspec
|
20
|
+
.DS_Store
|
21
|
+
/config.yml
|
22
|
+
/vcr_cassettes/
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Jay Stakelon
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# Redvine
|
2
|
+
|
3
|
+
A simple Ruby wrapper for the totally unofficial and undocumented [Vine](http://vine.co) API. Everyone loves Vine these days, and [this pretty much sums up why](http://www.youtube.com/watch?v=sdSJ1--kBZ4).
|
4
|
+
|
5
|
+
Very heavily inspired by [Vino](https://github.com/tlack/vino), and made possible by the super sleuthing documented on [khakimov.com](http://khakimov.com/blog/2013/03/12/vines-undocumented-api/).
|
6
|
+
|
7
|
+
It pretty much goes without saying that this wasn't authorized by Vine or anyone who works at Vine, so don't blame me if you try to use it and Vine gets mad at you.
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
gem install redvine
|
12
|
+
|
13
|
+
## Usage
|
14
|
+
|
15
|
+
require 'rubygems'
|
16
|
+
require 'redvine'
|
17
|
+
|
18
|
+
client = Redvine.new
|
19
|
+
|
20
|
+
# Connect to Vine with an email and password
|
21
|
+
client.connect(email: 'your@email.com', password: 'your_vine_password')
|
22
|
+
|
23
|
+
# Get your own timeline
|
24
|
+
client.timeline
|
25
|
+
|
26
|
+
# Find videos by tag
|
27
|
+
client.search('cats')
|
28
|
+
|
29
|
+
# Find user profiles by user ID
|
30
|
+
client.user_profile('908082141764657152')
|
31
|
+
|
32
|
+
# Get a user's timeline by their user ID
|
33
|
+
client.user_timeline('908082141764657152')
|
34
|
+
|
35
|
+
# Get popular and promoted videos
|
36
|
+
client.popular
|
37
|
+
client.promoted
|
38
|
+
|
39
|
+
### Things To Do
|
40
|
+
|
41
|
+
* Learn more about the API responses and objects
|
42
|
+
* Make it easier to access attributes of common objects (videos and users)
|
43
|
+
* Include all of the discovered API endpoints
|
44
|
+
|
45
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/config.yml_TEMPLATE
ADDED
data/lib/redvine.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
require 'redvine/version'
|
3
|
+
|
4
|
+
class Redvine
|
5
|
+
|
6
|
+
attr_reader :vine_key, :username, :user_id
|
7
|
+
|
8
|
+
@@baseUrl = 'https://api.vineapp.com/'
|
9
|
+
@@deviceToken = 'Redvine'
|
10
|
+
@@userAgent = 'com.vine.iphone/1.01 (unknown, iPhone OS 6.0, iPad, Scale/2.000000) (Redvine)'
|
11
|
+
|
12
|
+
def connect(opts={})
|
13
|
+
validate_connect_args(opts)
|
14
|
+
query = {username: opts[:email], password: opts[:password], deviceToken: @@deviceToken}
|
15
|
+
headers = {'User-Agent' => @@userAgent}
|
16
|
+
response = HTTParty.post(@@baseUrl + 'users/authenticate', {body: query, headers: headers})
|
17
|
+
@vine_key = response.parsed_response['data']['key']
|
18
|
+
@username = response.parsed_response['data']['username']
|
19
|
+
@user_id = response.parsed_response['data']['userId']
|
20
|
+
end
|
21
|
+
|
22
|
+
def search(tag)
|
23
|
+
raise(ArgumentError, 'You must specify a tag') if !tag
|
24
|
+
get_request_data('timelines/tags/' + tag)
|
25
|
+
end
|
26
|
+
|
27
|
+
def popular
|
28
|
+
get_request_data('timelines/popular')
|
29
|
+
end
|
30
|
+
|
31
|
+
def promoted
|
32
|
+
get_request_data('timelines/promoted')
|
33
|
+
end
|
34
|
+
|
35
|
+
def timeline
|
36
|
+
get_request_data('timelines/graph')
|
37
|
+
end
|
38
|
+
|
39
|
+
def user_profile(uid)
|
40
|
+
raise(ArgumentError, 'You must specify a user id') if !uid
|
41
|
+
get_request_data('users/profiles/' + uid, false)
|
42
|
+
end
|
43
|
+
|
44
|
+
def user_timeline(uid)
|
45
|
+
raise(ArgumentError, 'You must specify a user id') if !uid
|
46
|
+
get_request_data('timelines/users/' + uid)
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
private
|
51
|
+
def validate_connect_args(opts={})
|
52
|
+
unless opts.has_key?(:email) and opts.has_key?(:email)
|
53
|
+
raise(ArgumentError, 'You must specify both :email and :password')
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def session_headers
|
58
|
+
{'User-Agent' => @@userAgent, 'vine-session-id' => @vine_key}
|
59
|
+
end
|
60
|
+
|
61
|
+
def get_request_data(endpoint, records=true)
|
62
|
+
response = HTTParty.get(@@baseUrl + endpoint, {headers: session_headers})
|
63
|
+
records ? response.parsed_response['data']['records'] : response.parsed_response['data']
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
data/redvine.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'redvine/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "redvine"
|
8
|
+
gem.version = Redvine::VERSION
|
9
|
+
gem.authors = ["Jay Stakelon"]
|
10
|
+
gem.email = ["jay@stakelon.com"]
|
11
|
+
gem.description = %q{A client for the unofficial Vine API.}
|
12
|
+
gem.summary = gem.description
|
13
|
+
gem.homepage = "http://github.com/stakes/redvine"
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_dependency 'httparty'
|
21
|
+
|
22
|
+
gem.add_development_dependency 'rake'
|
23
|
+
gem.add_development_dependency 'rspec'
|
24
|
+
gem.add_development_dependency 'webmock'
|
25
|
+
gem.add_development_dependency 'vcr'
|
26
|
+
gem.add_development_dependency 'autotest-standalone'
|
27
|
+
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
require 'redvine'
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'vcr_setup'
|
4
|
+
|
5
|
+
include Helpers
|
6
|
+
|
7
|
+
describe Redvine do
|
8
|
+
|
9
|
+
describe '.connect' do
|
10
|
+
|
11
|
+
it 'should create a new client' do
|
12
|
+
expect(Redvine.new).to respond_to(:connect).with(1).argument
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should raise an error without a username and password' do
|
16
|
+
client = Redvine.new
|
17
|
+
expect { client.connect() }.to raise_error(ArgumentError)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should connect and return a hash with a :vine_key' do
|
21
|
+
VCR.use_cassette('redvine') do
|
22
|
+
config = get_config()
|
23
|
+
client = Redvine.new
|
24
|
+
client.connect(email: config['email'], password: config['password'])
|
25
|
+
expect(client.vine_key).to be_an_instance_of(String)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '.search' do
|
32
|
+
|
33
|
+
it 'should respond to a search method' do
|
34
|
+
VCR.use_cassette('redvine') do
|
35
|
+
client = setup_client()
|
36
|
+
expect(client).to respond_to(:search)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should throw an error without a tag' do
|
41
|
+
VCR.use_cassette('redvine') do
|
42
|
+
client = setup_client()
|
43
|
+
expect{ client.search() }.to raise_error(ArgumentError)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should return a result when searching for a common keyword' do
|
48
|
+
VCR.use_cassette('redvine', :record => :new_episodes) do
|
49
|
+
client = setup_client()
|
50
|
+
vines = client.search('cat')
|
51
|
+
expect(vines.count).to be > 1
|
52
|
+
expect(vines.first.has_key?('videoUrl')).to be_true
|
53
|
+
expect(vines.first.has_key?('avatarUrl')).to be_true
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
describe '.popular' do
|
60
|
+
|
61
|
+
it 'should respond to a popular method' do
|
62
|
+
expect(Redvine.new).to respond_to(:popular)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'should return a set of results with VideoUrls' do
|
66
|
+
VCR.use_cassette('redvine', :record => :new_episodes) do
|
67
|
+
client = setup_client()
|
68
|
+
vines = client.popular
|
69
|
+
expect(vines.count).to be > 1
|
70
|
+
expect(vines.first.has_key?('videoUrl')).to be_true
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
describe '.promoted' do
|
78
|
+
|
79
|
+
it 'should respond to a promoted method' do
|
80
|
+
expect(Redvine.new).to respond_to(:promoted)
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'should return a set of results with VideoUrls' do
|
84
|
+
VCR.use_cassette('redvine', :record => :new_episodes) do
|
85
|
+
client = setup_client()
|
86
|
+
vines = client.promoted
|
87
|
+
expect(vines.count).to be > 1
|
88
|
+
expect(vines.first.has_key?('videoUrl')).to be_true
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
describe '.timeline' do
|
95
|
+
|
96
|
+
it 'should respond to a timeline method' do
|
97
|
+
expect(Redvine.new).to respond_to(:timeline)
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'should return a set of results with VideoUrls' do
|
101
|
+
VCR.use_cassette('redvine', :record => :new_episodes) do
|
102
|
+
client = setup_client()
|
103
|
+
vines = client.timeline
|
104
|
+
expect(vines.count).to be > 1
|
105
|
+
expect(vines.first.has_key?('videoUrl')).to be_true
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
describe '.user_profile' do
|
112
|
+
|
113
|
+
it 'should respond to a user_profile method' do
|
114
|
+
expect(Redvine.new).to respond_to(:user_profile)
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'should throw an error without a user id' do
|
118
|
+
client = Redvine.new
|
119
|
+
expect { client.user_profile() }.to raise_error(ArgumentError)
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'should return a user profile for the authenticated user' do
|
123
|
+
VCR.use_cassette('redvine', :record => :new_episodes) do
|
124
|
+
client = setup_client()
|
125
|
+
profile = client.user_profile(client.user_id.to_s)
|
126
|
+
expect(profile.has_key?('userId')).to be_true
|
127
|
+
expect(profile.has_key?('username')).to be_true
|
128
|
+
expect(profile.has_key?('avatarUrl')).to be_true
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'should return a user profile given a valid user id' do
|
133
|
+
VCR.use_cassette('redvine', :record => :new_episodes) do
|
134
|
+
client = setup_client()
|
135
|
+
profile = client.user_profile('914021455983943680')
|
136
|
+
expect(profile.has_key?('userId')).to be_true
|
137
|
+
expect(profile.has_key?('username')).to be_true
|
138
|
+
expect(profile.has_key?('avatarUrl')).to be_true
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
143
|
+
|
144
|
+
describe '.user_timeline' do
|
145
|
+
|
146
|
+
it 'should respond to a user_timeline method' do
|
147
|
+
expect(Redvine.new).to respond_to(:user_timeline)
|
148
|
+
end
|
149
|
+
|
150
|
+
it 'should throw an error without a user id' do
|
151
|
+
client = Redvine.new
|
152
|
+
expect { client.user_timeline() }.to raise_error(ArgumentError)
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'should return a set of results with VideoUrls given a valid user id' do
|
156
|
+
VCR.use_cassette('redvine', :record => :new_episodes) do
|
157
|
+
client = setup_client()
|
158
|
+
vines = client.user_timeline('914021455983943680')
|
159
|
+
expect(vines.count).to be > 1
|
160
|
+
expect(vines.first.has_key?('videoUrl')).to be_true
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
|
166
|
+
|
167
|
+
|
168
|
+
|
169
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
module Helpers
|
2
|
+
def setup_client
|
3
|
+
config = get_config()
|
4
|
+
client = Redvine.new
|
5
|
+
client.connect(email: config['email'], password: config['password'])
|
6
|
+
client
|
7
|
+
end
|
8
|
+
|
9
|
+
def get_config
|
10
|
+
raw_config = File.read('config.yml')
|
11
|
+
config = YAML.load(raw_config)
|
12
|
+
end
|
13
|
+
end
|
data/spec/vcr_setup.rb
ADDED
metadata
ADDED
@@ -0,0 +1,156 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: redvine
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jay Stakelon
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-06-29 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: httparty
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rspec
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: webmock
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: vcr
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: autotest-standalone
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
description: A client for the unofficial Vine API.
|
111
|
+
email:
|
112
|
+
- jay@stakelon.com
|
113
|
+
executables: []
|
114
|
+
extensions: []
|
115
|
+
extra_rdoc_files: []
|
116
|
+
files:
|
117
|
+
- .gitignore
|
118
|
+
- Gemfile
|
119
|
+
- LICENSE.txt
|
120
|
+
- README.md
|
121
|
+
- Rakefile
|
122
|
+
- config.yml_TEMPLATE
|
123
|
+
- lib/redvine.rb
|
124
|
+
- lib/redvine/version.rb
|
125
|
+
- redvine.gemspec
|
126
|
+
- spec/redvine_spec.rb
|
127
|
+
- spec/spec_helper.rb
|
128
|
+
- spec/vcr_setup.rb
|
129
|
+
homepage: http://github.com/stakes/redvine
|
130
|
+
licenses: []
|
131
|
+
post_install_message:
|
132
|
+
rdoc_options: []
|
133
|
+
require_paths:
|
134
|
+
- lib
|
135
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
136
|
+
none: false
|
137
|
+
requirements:
|
138
|
+
- - ! '>='
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: '0'
|
141
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
142
|
+
none: false
|
143
|
+
requirements:
|
144
|
+
- - ! '>='
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '0'
|
147
|
+
requirements: []
|
148
|
+
rubyforge_project:
|
149
|
+
rubygems_version: 1.8.24
|
150
|
+
signing_key:
|
151
|
+
specification_version: 3
|
152
|
+
summary: A client for the unofficial Vine API.
|
153
|
+
test_files:
|
154
|
+
- spec/redvine_spec.rb
|
155
|
+
- spec/spec_helper.rb
|
156
|
+
- spec/vcr_setup.rb
|