instagram-private-api 0.1.5.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,18 +1,78 @@
1
- module Instagram
2
- module Feed
3
- def self.user_media(user, data)
4
- user_id = (!data[:id].nil? ? data[:id] : user.data[:id])
5
- rank_token = Instagram::API.generate_rank_token user.session.scan(/ds_user_id=([\d]+);/)[0][0]
6
- endpoint = "https://i.instagram.com/api/v1/feed/user/#{user_id}/"
7
- param = "?rank_token=#{rank_token}" +
8
- (!data[:max_id].nil? ? '&max_id=' + data[:max_id] : '')
9
- result = Instagram::API.http(
10
- url: endpoint + param,
11
- method: 'GET',
12
- user: user
13
- )
14
-
15
- JSON.parse result.body
16
- end
17
- end
18
- end
1
+ module Instagram
2
+ class Feed
3
+ def initialize
4
+ @api = V1.singleton
5
+ end
6
+
7
+ def using user
8
+ @user = {
9
+ id: user.data[:id],
10
+ session: user.session,
11
+ ua: user.useragent
12
+ }
13
+ self
14
+ end
15
+
16
+ def timeline_media
17
+ user_id = @user[:id]
18
+
19
+ rank_token = Instagram::V1.generate_rank_token @user[:id]
20
+ endpoint = "https://i.instagram.com/api/v1/feed/user/#{user_id}/"
21
+ param = "?rank_token=#{rank_token}"
22
+ result = @api.get(endpoint + param)
23
+ .with(session: @user[:session], ua: @user[:ua]).exec
24
+
25
+ JSON.parse result.body
26
+ end
27
+
28
+ def self.user_followers(user, data, limit)
29
+ has_next_page = true
30
+ followers = []
31
+ user_id = (!data[:id].nil? ? data[:id] : user.data[:id])
32
+ data[:rank_token] = Instagram::API.generate_rank_token user.session.scan(/ds_user_id=([\d]+);/)[0][0]
33
+ while has_next_page && limit > followers.size
34
+ response = user_followers_next_page(user, user_id, data)
35
+ has_next_page = !response['next_max_id'].nil?
36
+ data[:max_id] = response['next_max_id']
37
+ followers += response['users']
38
+ end
39
+ limit.infinite? ? followers : followers[0...limit]
40
+ end
41
+
42
+ def self.user_followers_graphql(user, data, limit)
43
+ has_next_page = true
44
+ followers = []
45
+ user_id = (!data[:id].nil? ? data[:id] : user.data[:id])
46
+ while has_next_page && limit > followers.size
47
+ response = user_followers_graphql_next_page(user, user_id, data)
48
+ has_next_page = response['data']['user']['edge_followed_by']['page_info']['has_next_page']
49
+ data[:end_cursor] = response['data']['user']['edge_followed_by']['page_info']['end_cursor']
50
+ followers += response['data']['user']['edge_followed_by']['edges']
51
+ end
52
+ limit.infinite? ? followers : followers[0...limit]
53
+ end
54
+
55
+ def self.user_followers_graphql_next_page(user, user_id, data)
56
+ endpoint = "https://www.instagram.com/graphql/query/?query_id=17851374694183129&id=#{user_id}&first=5000"
57
+ param = (!data[:end_cursor].nil? ? "&after=#{data[:end_cursor]}" : '')
58
+ result = Instagram::API.http(
59
+ url: endpoint + param,
60
+ method: 'GET',
61
+ user: user
62
+ )
63
+ JSON.parse result.body
64
+ end
65
+
66
+ def self.user_followers_next_page(user, user_id, data)
67
+ endpoint = "https://i.instagram.com/api/v1/friendships/#{user_id}/followers/"
68
+ param = "?rank_token=#{data[:rank_token]}" +
69
+ (!data[:max_id].nil? ? '&max_id=' + data[:max_id] : '')
70
+ result = Instagram::API.http(
71
+ url: endpoint + param,
72
+ method: 'GET',
73
+ user: user
74
+ )
75
+ JSON.parse result.body
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Instagram
4
+ class Relationship
5
+ def initialize user
6
+ @user = user
7
+ @api = nil
8
+ end
9
+
10
+ def create(id)
11
+ api.post("https://i.instagram.com/api/v1/friendships/create/#{id}/",
12
+ format(
13
+ 'ig_sig_key_version=4&signed_body=%s',
14
+ V1.generate_signature(
15
+ user_id: id
16
+ )
17
+ )).with(session: @user.session, ua: @user.useragent).exec
18
+ end
19
+
20
+ def api
21
+ @api = V1.new if @api.nil?
22
+
23
+ @api
24
+ end
25
+ end
26
+ end
@@ -1,84 +1,118 @@
1
- require 'digest/md5'
2
- require 'Instagram/Device'
3
- require 'Instagram/CONSTANTS'
4
-
5
- module Instagram
6
- class User
7
- attr_reader :username
8
- attr_reader :password
9
- attr_reader :language
10
- attr_reader :data
11
- attr_writer :data
12
- attr_reader :session
13
- attr_writer :session
14
-
15
- def initialize(username, password, session = nil, data = nil)
16
- @username = username
17
- @password = password
18
- @language = 'en_US'
19
- @session = session
20
- @data = data
21
- end
22
-
23
- def search_for_user (username)
24
- Instagram::Account.search_for_user(self, username)
25
- end
26
-
27
- def user_media(data = {})
28
- Instagram::Feed.user_media(self, data)
29
- end
30
-
31
- def md5
32
- Digest::MD5.hexdigest @username
33
- end
34
-
35
- def md5int
36
- (md5.to_i(32) / 10e32).round
37
- end
38
-
39
- def api
40
- (18 + (md5int % 5)).to_s
41
- end
42
-
43
- # @return [string]
44
- def release
45
- %w[4.0.4 4.3.1 4.4.4 5.1.1 6.0.1][md5int % 5]
46
- end
47
-
48
- def dpi
49
- %w[801 577 576 538 515 424 401 373][md5int % 8]
50
- end
51
-
52
- def resolution
53
- %w[3840x2160 1440x2560 2560x1440 1440x2560
54
- 2560x1440 1080x1920 1080x1920 1080x1920][md5int % 8]
55
- end
56
-
57
- def info
58
- line = Device.devices[md5int % Device.devices.count]
59
- {
60
- manufacturer: line[0],
61
- device: line[1],
62
- model: line[2]
63
- }
64
- end
65
-
66
- def useragent_hash
67
- agent = [api + '/' + release, dpi + 'dpi',
68
- resolution, info[:manufacturer], info[:model], info[:device], @language]
69
-
70
- {
71
- agent: agent.join('; '),
72
- version: CONSTANTS::PRIVATE_KEY[:APP_VERSION]
73
- }
74
- end
75
-
76
- def useragent
77
- format('Instagram %s Android(%s)', useragent_hash[:version], useragent_hash[:agent].rstrip)
78
- end
79
-
80
- def device_id
81
- 'android-' + md5[0..15]
82
- end
83
- end
84
- end
1
+ require 'digest/md5'
2
+ require 'Instagram/Device'
3
+ require 'Instagram/CONSTANTS'
4
+
5
+ module Instagram
6
+ class User
7
+ attr_reader :username
8
+ attr_reader :password
9
+ attr_reader :language
10
+ attr_reader :data
11
+ attr_writer :data
12
+ attr_reader :session
13
+ attr_writer :session
14
+ attr_reader :config
15
+ attr_writer :config
16
+
17
+ def initialize(username, password, session = nil, data = nil, config = nil)
18
+ @username = username
19
+ @password = password
20
+ @language = 'en_US'
21
+ @session = session
22
+ @data = data
23
+ @config = config
24
+ @account = nil
25
+ @feed = nil
26
+ end
27
+
28
+ def search_for_user(username)
29
+ account.search_for_user(self, username)
30
+ end
31
+
32
+ def search_for_user_graphql(username)
33
+ account.search_for_graphql(self, username)
34
+ end
35
+
36
+ def followers(limit = Float::INFINITY, data = {})
37
+ Instagram::Feed.user_followers(self, data, limit)
38
+ end
39
+
40
+ def user_followers_graphql(limit = Float::INFINITY, data = {})
41
+ Instagram::Feed.user_followers_graphql(self, data, limit)
42
+ end
43
+
44
+ def relationship
45
+ unless instance_variable_defined? :@relationship
46
+ @relationship = Relationship.new self
47
+ end
48
+
49
+ @relationship
50
+ end
51
+
52
+ def account
53
+ @account = Instagram::Account.new if @account.nil?
54
+
55
+ @account
56
+ end
57
+
58
+ def feed
59
+ @feed = Instagram::Feed.new if @feed.nil?
60
+
61
+ @feed.using(self)
62
+ end
63
+
64
+ def md5
65
+ Digest::MD5.hexdigest @username
66
+ end
67
+
68
+ def md5int
69
+ (md5.to_i(32) / 10e32).round
70
+ end
71
+
72
+ def api
73
+ (18 + (md5int % 5)).to_s
74
+ end
75
+
76
+ # @return [string]
77
+ def release
78
+ %w[4.0.4 4.3.1 4.4.4 5.1.1 6.0.1][md5int % 5]
79
+ end
80
+
81
+ def dpi
82
+ %w[801 577 576 538 515 424 401 373][md5int % 8]
83
+ end
84
+
85
+ def resolution
86
+ %w[3840x2160 1440x2560 2560x1440 1440x2560
87
+ 2560x1440 1080x1920 1080x1920 1080x1920][md5int % 8]
88
+ end
89
+
90
+ def info
91
+ line = Device.devices[md5int % Device.devices.count]
92
+ {
93
+ manufacturer: line[0],
94
+ device: line[1],
95
+ model: line[2]
96
+ }
97
+ end
98
+
99
+ def useragent_hash
100
+ agent = [api + '/' + release, dpi + 'dpi',
101
+ resolution, info[:manufacturer],
102
+ info[:model], info[:device], @language]
103
+
104
+ {
105
+ agent: agent.join('; '),
106
+ version: CONSTANTS::PRIVATE_KEY[:APP_VERSION]
107
+ }
108
+ end
109
+
110
+ def useragent
111
+ format('Instagram %s Android(%s)', useragent_hash[:version], useragent_hash[:agent].rstrip)
112
+ end
113
+
114
+ def device_id
115
+ 'android-' + md5[0..15]
116
+ end
117
+ end
118
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: instagram-private-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - vicoerv
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-11-10 00:00:00.000000000 Z
11
+ date: 2018-07-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -60,10 +60,13 @@ executables: []
60
60
  extensions: []
61
61
  extra_rdoc_files: []
62
62
  files:
63
+ - ".gitignore"
63
64
  - ".rspec"
65
+ - ".rubocop.yml"
64
66
  - ".travis.yml"
65
67
  - CODE_OF_CONDUCT.md
66
68
  - Gemfile
69
+ - Gemfile.lock
67
70
  - Instagram-API.gemspec
68
71
  - LICENSE.txt
69
72
  - README.md
@@ -74,9 +77,11 @@ files:
74
77
  - lib/Instagram/API/version.rb
75
78
  - lib/Instagram/account.rb
76
79
  - lib/Instagram/api.rb
80
+ - lib/Instagram/configuration.rb
77
81
  - lib/Instagram/constants.rb
78
82
  - lib/Instagram/device.rb
79
83
  - lib/Instagram/feed.rb
84
+ - lib/Instagram/relationship.rb
80
85
  - lib/Instagram/user.rb
81
86
  homepage: http://www.vicoervanda.com
82
87
  licenses:
@@ -99,7 +104,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
99
104
  version: '0'
100
105
  requirements: []
101
106
  rubyforge_project:
102
- rubygems_version: 2.5.2
107
+ rubygems_version: 2.7.6
103
108
  signing_key:
104
109
  specification_version: 4
105
110
  summary: Instagram private api, implemented from huttarichard/instagram-private-api