social_net 0.2.11 → 0.2.12
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 +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +0 -2
- data/lib/social_net/instagram/api/scrape_request.rb +3 -2
- data/lib/social_net/instagram/api/scrape_user_videos_request.rb +71 -0
- data/lib/social_net/instagram/models/user.rb +5 -5
- data/lib/social_net/version.rb +1 -1
- data/social_net.gemspec +1 -2
- data/spec/social_net/instagram/models/user_spec.rb +1 -1
- data/spec/spec_helper.rb +1 -0
- data/spec/support/cassettes/SocialNet_Instagram_Models_User/_videos/given_an_existing_user/returns_an_array_of_video_posts_from_the_user.yml +188 -748
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d501f1bc53f1dcdee920829ddb5070d891bb1c74
|
4
|
+
data.tar.gz: a475f8ccd93d602887ec8affca0f6489f9cc5cf8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7e3f919d2d081c21c68194f3aaa13d9e4493d4ba618b516ea0b9854cdc43f464b581b7c417a17738cc4a901e9f9683ece6f67dfb6adfb1c664e15f2d51fcfce5
|
7
|
+
data.tar.gz: 10f6239c2dff174385f827b2b416206f0ef7fd461624c373373712e9c400e71b5cc18bae981bca192e0e32a77da3dabbf065f67ed4c7eca489beaa23df391929
|
data/CHANGELOG.md
CHANGED
@@ -46,3 +46,7 @@ For more information about changelogs, check
|
|
46
46
|
|
47
47
|
* [BUGFIX] Remove deprecated `find_by media_id` endpoint.
|
48
48
|
* [IMPROVEMENT] Remove `find_by private_shortcode`.
|
49
|
+
|
50
|
+
## 0.2.12 - 2018-06-04
|
51
|
+
|
52
|
+
* [BUGFIX] Update deprecated `user.videos` method and add scraping support.
|
data/README.md
CHANGED
@@ -114,8 +114,6 @@ video.link #=> 'https://www.instagram.com/p/BW-nC7xg8ZX/'
|
|
114
114
|
video.file #=> 'https://scontent.cdninstagram.com/t50.2886-16/20372137_156190564936990_2601958215176421376_n.mp4'
|
115
115
|
```
|
116
116
|
|
117
|
-
*The methods above require a configured Instagram app (see below).*
|
118
|
-
|
119
117
|
SocialNet::Facebook::Page
|
120
118
|
--------------------
|
121
119
|
|
@@ -42,8 +42,9 @@ module SocialNet
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def parse_video_data(data)
|
45
|
-
|
46
|
-
|
45
|
+
script_with_data = data.search("script").detect {|script| script.children[0].content.include? "window._sharedData"}
|
46
|
+
data_string = script_with_data.children[0].content
|
47
|
+
ig_data = eval data_string.gsub(/window\._sharedData = /,"").gsub(/null/,'nil').gsub(/\\/,'')
|
47
48
|
video_data = ig_data[:entry_data][:PostPage][0][:graphql][:shortcode_media]
|
48
49
|
raise Errors::UnknownVideo unless video_data[:is_video]
|
49
50
|
{}.tap do |video|
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'social_net/instagram/errors/response_error'
|
2
|
+
require 'social_net/instagram/errors/unknown_user'
|
3
|
+
require 'active_support'
|
4
|
+
require 'active_support/core_ext'
|
5
|
+
require 'nokogiri'
|
6
|
+
|
7
|
+
module SocialNet
|
8
|
+
module Instagram
|
9
|
+
module Api
|
10
|
+
class ScrapeUserVideosRequest
|
11
|
+
def initialize(attrs = {})
|
12
|
+
@host = 'www.instagram.com'
|
13
|
+
@path = attrs.fetch :path, "/#{attrs[:username]}/"
|
14
|
+
@method = attrs.fetch :method, :get
|
15
|
+
end
|
16
|
+
|
17
|
+
def run
|
18
|
+
print "#{as_curl}\n"
|
19
|
+
case response = run_http_request
|
20
|
+
when Net::HTTPOK
|
21
|
+
data_string = Nokogiri::HTML response.body
|
22
|
+
parse_video_data data_string
|
23
|
+
else
|
24
|
+
raise Errors::ResponseError, response
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
def run_http_request
|
30
|
+
Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
|
31
|
+
http.request http_request
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def http_request
|
36
|
+
http_class = "Net::HTTP::#{@method.capitalize}".constantize
|
37
|
+
@http_request ||= http_class.new(uri.request_uri)
|
38
|
+
end
|
39
|
+
|
40
|
+
def uri
|
41
|
+
@uri ||= URI::HTTPS.build host: @host, path: @path
|
42
|
+
end
|
43
|
+
|
44
|
+
def parse_video_data(data)
|
45
|
+
data_string = data.search("script")[3].children.first
|
46
|
+
ig_data = eval data_string.content.gsub(/window\._sharedData = /,"").gsub(/null/,'nil').gsub(/\\/,'')
|
47
|
+
user_data = ig_data[:entry_data][:ProfilePage][0][:graphql][:user][:edge_owner_to_timeline_media][:edges]
|
48
|
+
vs = [].tap do |videos|
|
49
|
+
user_data.each do |data|
|
50
|
+
if data[:node][:__typename] == "GraphVideo"
|
51
|
+
video = Models::Video.find_by shortcode: data[:node][:shortcode]
|
52
|
+
videos << video
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def as_curl
|
59
|
+
'curl'.tap do |curl|
|
60
|
+
curl << " -X #{http_request.method}"
|
61
|
+
http_request.each_header do |name, value|
|
62
|
+
curl << %Q{ -H "#{name}: #{value}"}
|
63
|
+
end
|
64
|
+
curl << %Q{ -d '#{http_request.body}'} if http_request.body
|
65
|
+
curl << %Q{ "#{@uri.to_s}"}
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'social_net/instagram/api/request'
|
2
|
+
require 'social_net/instagram/api/scrape_user_videos_request'
|
2
3
|
require 'social_net/instagram/errors'
|
3
4
|
|
4
5
|
module SocialNet
|
@@ -9,17 +10,16 @@ module SocialNet
|
|
9
10
|
|
10
11
|
def initialize(attrs = {})
|
11
12
|
@id = attrs['id']
|
12
|
-
@username = attrs[
|
13
|
-
@follower_count = attrs['counts']['followed_by']
|
13
|
+
@username = attrs[:username]
|
14
|
+
@follower_count = attrs['counts']['followed_by'] if attrs['counts']
|
14
15
|
end
|
15
16
|
|
16
17
|
# Returns the existing Instagram user's most recent videos
|
17
18
|
#
|
18
19
|
# @return [SocialNet::Instagram::Models::Video] when the videos are found.
|
19
20
|
def videos
|
20
|
-
request = Api::
|
21
|
-
|
22
|
-
videos.map {|r| SocialNet::Instagram::Video.new r }
|
21
|
+
request = Api::ScrapeUserVideosRequest.new username: @username
|
22
|
+
request.run
|
23
23
|
rescue Errors::ResponseError => error
|
24
24
|
case error.response
|
25
25
|
when Net::HTTPBadRequest then raise Errors::UnknownUser
|
data/lib/social_net/version.rb
CHANGED
data/social_net.gemspec
CHANGED
@@ -20,12 +20,11 @@ Gem::Specification.new do |spec|
|
|
20
20
|
|
21
21
|
spec.add_dependency 'activesupport'
|
22
22
|
spec.add_dependency 'nokogiri'
|
23
|
-
|
24
23
|
spec.add_development_dependency "bundler", "~> 1.6"
|
25
24
|
spec.add_development_dependency "rake", "~> 10.3"
|
26
25
|
spec.add_development_dependency "rspec", "~> 3.1"
|
27
26
|
spec.add_development_dependency "yard", "~> 0.8.7"
|
28
27
|
spec.add_development_dependency "coveralls", "~> 0.7.1"
|
29
28
|
spec.add_development_dependency "vcr", "~> 2.9"
|
30
|
-
spec.add_development_dependency "webmock", "~> 1
|
29
|
+
spec.add_development_dependency "webmock", "~> 3.4.1"
|
31
30
|
end
|
@@ -56,7 +56,7 @@ describe SocialNet::Instagram::User, :vcr do
|
|
56
56
|
end
|
57
57
|
|
58
58
|
describe '.videos' do
|
59
|
-
subject(:user) { SocialNet::Instagram::User.
|
59
|
+
subject(:user) { SocialNet::Instagram::User.new username: username }
|
60
60
|
context 'given an existing user' do
|
61
61
|
let(:username) { existing_username }
|
62
62
|
|