social_profile 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/social_profile/people/facebook.rb +23 -4
- data/lib/social_profile/people/twitter.rb +50 -0
- data/lib/social_profile/people/vkontakte.rb +186 -0
- data/lib/social_profile/providers/odnoklassniki.rb +74 -0
- data/lib/social_profile/version.rb +1 -1
- data/lib/social_profile.rb +2 -0
- data/social_profile.gemspec +3 -3
- data/spec/mock_json/facebook/followers_5_0.json +34 -0
- data/spec/mock_json/facebook/followers_5_10.json +35 -0
- data/spec/mock_json/facebook/followers_5_15.json +26 -0
- data/spec/mock_json/twitter/auth.json +1 -1
- data/spec/mock_json/twitter/last_posts.json +4326 -0
- data/spec/mock_json/vkontakte/comments_photos.json +707 -0
- data/spec/mock_json/vkontakte/comments_post_655.json +42 -0
- data/spec/mock_json/vkontakte/followers.json +187 -0
- data/spec/mock_json/vkontakte/followers_20.json +127 -0
- data/spec/mock_json/vkontakte/followers_20_2.json +67 -0
- data/spec/mock_json/vkontakte/friends.json +1728 -0
- data/spec/mock_json/vkontakte/last_posts.json +4279 -0
- data/spec/mock_json/vkontakte/last_posts_2.json +2736 -0
- data/spec/mock_json/vkontakte/last_posts_3.json +533 -0
- data/spec/mock_json/vkontakte/likes_photo_290498375.json +24 -0
- data/spec/mock_json/vkontakte/likes_post_655.json +14 -0
- data/spec/mock_json/vkontakte/shares_post_3675.json +1373 -0
- data/spec/people/facebook_spec.rb +25 -0
- data/spec/people/twitter_spec.rb +21 -1
- data/spec/people/vkontakte_spec.rb +95 -3
- data/spec/spec_helper.rb +1 -1
- metadata +47 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9ff2a46cb1b8edb78c457fb204d2efac1035b642
|
4
|
+
data.tar.gz: e843f72028951caa385e61478566a2eda9ba31ae
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 889b1b58ae675301c69a86282700b552cae13d99f441bacf9b2d74c579e06110942fddaadd687a1f075420b9fc0436d5d953628be875fe7c2315db83245f00dc
|
7
|
+
data.tar.gz: 9108fb8234539617a98bf26c94247515a10b32b7e804b697e365e5d6d45fd7048f944c990086815ebabec2ffd90e1c6c72b718ec0ea4b2f2ba354f0b4cbedc6f
|
@@ -70,11 +70,16 @@ module SocialProfile
|
|
70
70
|
def last_post_by_days(days, options={})
|
71
71
|
date = (options[:date_end] || Time.now) - days.days
|
72
72
|
limit = options[:limit] || 100
|
73
|
+
max_iteration = options[:max_iteration] || 100
|
74
|
+
iteration = 0
|
73
75
|
|
74
76
|
posts = collection = last_posts(limit, options)
|
77
|
+
return [] if posts.blank?
|
78
|
+
|
75
79
|
last_created_time = posts.last.created_time
|
76
80
|
|
77
|
-
while last_created_time > date
|
81
|
+
while last_created_time > date && !last_created_time.blank? && iteration < max_iteration
|
82
|
+
iteration += 1
|
78
83
|
collection = collection.next
|
79
84
|
posts += collection
|
80
85
|
last_created_time = posts.last.created_time
|
@@ -86,15 +91,29 @@ module SocialProfile
|
|
86
91
|
# Get all friends list
|
87
92
|
#
|
88
93
|
def friends(options={})
|
89
|
-
limit = options[:limit] ||
|
94
|
+
limit = options[:limit] || 5000
|
90
95
|
user.friends(:limit => limit)
|
91
96
|
end
|
92
97
|
|
93
98
|
# Get all followers list
|
94
99
|
#
|
95
100
|
def followers(options={})
|
96
|
-
limit = options[:limit] ||
|
97
|
-
|
101
|
+
limit = options[:limit] || 5000
|
102
|
+
fetch_all = options[:fetch_all] || false
|
103
|
+
iteration = 0
|
104
|
+
|
105
|
+
_followers = collection = user.subscribers(:limit => limit)
|
106
|
+
max_iteration = _followers.total_count / limit + 1
|
107
|
+
|
108
|
+
if fetch_all
|
109
|
+
while iteration < max_iteration
|
110
|
+
iteration += 1
|
111
|
+
collection = collection.next
|
112
|
+
_followers += collection
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
_followers
|
98
117
|
end
|
99
118
|
|
100
119
|
protected
|
@@ -3,6 +3,7 @@ require "twitter"
|
|
3
3
|
module SocialProfile
|
4
4
|
module People
|
5
5
|
class Twitter < Person
|
6
|
+
MAX_ATTEMPTS = 3
|
6
7
|
|
7
8
|
# Get friends count
|
8
9
|
def friends_count
|
@@ -12,6 +13,55 @@ module SocialProfile
|
|
12
13
|
def fetch_friends_count
|
13
14
|
client.user.followers_count
|
14
15
|
end
|
16
|
+
|
17
|
+
# Get last limited tweets from user_timeline, max 200 by query
|
18
|
+
#
|
19
|
+
def last_posts(uid, options = {})
|
20
|
+
params = {
|
21
|
+
:count => 200,
|
22
|
+
:exclude_replies => true,
|
23
|
+
:trim_user => true,
|
24
|
+
:include_rts => false
|
25
|
+
}
|
26
|
+
|
27
|
+
params.merge!(options)
|
28
|
+
|
29
|
+
with_atterms do
|
30
|
+
client.user_timeline(uid, params)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def get_all_tweets(uid, options = {})
|
35
|
+
collect_with_max_id do |max_id|
|
36
|
+
options[:max_id] = max_id unless max_id.nil?
|
37
|
+
last_posts(uid, options)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def collect_with_max_id(collection=[], max_id=nil, &block)
|
42
|
+
response = yield(max_id)
|
43
|
+
collection += response
|
44
|
+
response.empty? ? collection.flatten : collect_with_max_id(collection, response.last.id - 1, &block)
|
45
|
+
end
|
46
|
+
|
47
|
+
def with_atterms
|
48
|
+
num_attempts = 0
|
49
|
+
|
50
|
+
begin
|
51
|
+
num_attempts += 1
|
52
|
+
yield if block_given?
|
53
|
+
rescue ::Twitter::Error::TooManyRequests => error
|
54
|
+
if num_attempts <= MAX_ATTEMPTS
|
55
|
+
# NOTE: Your process could go to sleep for up to 15 minutes but if you
|
56
|
+
# retry any sooner, it will almost certainly fail with the same exception.
|
57
|
+
sleep error.rate_limit.reset_in
|
58
|
+
retry
|
59
|
+
else
|
60
|
+
raise
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
15
65
|
|
16
66
|
protected
|
17
67
|
|
@@ -33,12 +33,198 @@ module SocialProfile
|
|
33
33
|
|
34
34
|
counters["friends"].to_i + counters["followers"].to_i
|
35
35
|
end
|
36
|
+
|
37
|
+
# Get last limited posts from user_timeline, max 100 by query
|
38
|
+
#
|
39
|
+
def last_posts(options = {})
|
40
|
+
params = {
|
41
|
+
:owner_id => user.identifier,
|
42
|
+
:count => 100,
|
43
|
+
:filter => "owner",
|
44
|
+
:offset => 0
|
45
|
+
}
|
46
|
+
|
47
|
+
params.merge!(options)
|
48
|
+
|
49
|
+
fetch_all_method_items_with_days("wall.get", params)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Get last posts by N days from user_timeline
|
53
|
+
#
|
54
|
+
def last_post_by_days(days, options = {})
|
55
|
+
options = { :days => days }.merge(options)
|
56
|
+
|
57
|
+
last_posts(options)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Get object likes (post, comment, photo, audio, video, note, photo_comment, video_comment, topic_comment, sitepage)
|
61
|
+
#
|
62
|
+
def object_likes(uid, options = {})
|
63
|
+
fetch_all = options.delete(:fetch_all)
|
64
|
+
|
65
|
+
params = {
|
66
|
+
:owner_id => user.identifier,
|
67
|
+
:count => 1000,
|
68
|
+
:type => "post",
|
69
|
+
:item_id => uid,
|
70
|
+
:offset => 0
|
71
|
+
}
|
72
|
+
params.merge!(options)
|
73
|
+
|
74
|
+
if fetch_all
|
75
|
+
return fetch_all_method_items("likes.getList", params)
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
user.likes.getList(params)
|
80
|
+
end
|
81
|
+
|
82
|
+
# Get post comments
|
83
|
+
#
|
84
|
+
def post_comments(uid, options = {})
|
85
|
+
fetch_all = options.delete(:fetch_all)
|
86
|
+
|
87
|
+
params = {
|
88
|
+
:owner_id => user.identifier,
|
89
|
+
:count => 100,
|
90
|
+
:preview_length => 0,
|
91
|
+
:need_likes => 1,
|
92
|
+
:post_id => uid,
|
93
|
+
:offset => 0
|
94
|
+
}
|
95
|
+
params.merge!(options)
|
96
|
+
|
97
|
+
if fetch_all
|
98
|
+
return fetch_all_method_items("wall.getComments", params)
|
99
|
+
end
|
100
|
+
|
101
|
+
user.wall.getComments(params)
|
102
|
+
end
|
103
|
+
|
104
|
+
# Get post shares
|
105
|
+
#
|
106
|
+
def post_shares(uid, options = {})
|
107
|
+
fetch_all = options.delete(:fetch_all)
|
108
|
+
|
109
|
+
params = {
|
110
|
+
:owner_id => user.identifier,
|
111
|
+
:count => 1000,
|
112
|
+
:post_id => uid,
|
113
|
+
:offset => 0
|
114
|
+
}
|
115
|
+
params.merge!(options)
|
116
|
+
|
117
|
+
if fetch_all
|
118
|
+
return fetch_all_method_items("wall.getReposts", params)
|
119
|
+
end
|
120
|
+
|
121
|
+
user.wall.getReposts(params)
|
122
|
+
end
|
123
|
+
|
124
|
+
# Get all photos comments
|
125
|
+
#
|
126
|
+
def photos_comments(options = {})
|
127
|
+
params = {
|
128
|
+
:owner_id => user.identifier,
|
129
|
+
:count => 100,
|
130
|
+
:need_likes => 1,
|
131
|
+
:offset => 0
|
132
|
+
}
|
133
|
+
|
134
|
+
params.merge!(options)
|
135
|
+
|
136
|
+
fetch_all_method_items_with_days("photos.getAllComments", params)
|
137
|
+
end
|
138
|
+
|
139
|
+
# Get all photos comments by days
|
140
|
+
#
|
141
|
+
def photos_comments_by_days(days, options = {})
|
142
|
+
options = { :days => days }.merge(options)
|
143
|
+
|
144
|
+
photos_comments(options)
|
145
|
+
end
|
146
|
+
|
147
|
+
# Get all friends list
|
148
|
+
#
|
149
|
+
def friends(options={})
|
150
|
+
options = {
|
151
|
+
:count => 5000,
|
152
|
+
:offset => 0,
|
153
|
+
:fields => "domain"
|
154
|
+
}.merge(options)
|
155
|
+
|
156
|
+
fetch_all_method_items(:fetch_friends, options)
|
157
|
+
end
|
158
|
+
|
159
|
+
# Get all followers list
|
160
|
+
#
|
161
|
+
def followers(options={})
|
162
|
+
options = {
|
163
|
+
:count => 1000,
|
164
|
+
:offset => 0,
|
165
|
+
:fields => "screen_name"
|
166
|
+
}.merge(options)
|
167
|
+
|
168
|
+
fetch_all_method_items(:fetch_followers, options)
|
169
|
+
end
|
36
170
|
|
37
171
|
protected
|
38
172
|
|
39
173
|
def user
|
40
174
|
@user ||= ::Vkontakte::App::User.new(uid, :access_token => access_token)
|
41
175
|
end
|
176
|
+
|
177
|
+
def fetch_all_method_items(name, options)
|
178
|
+
methods = name.to_s.split(".")
|
179
|
+
response = methods.size == 2 ? user.send(methods[0]).send(methods[1], options) : user.send(name, options)
|
180
|
+
|
181
|
+
_items = response["items"]
|
182
|
+
return [] if _items.blank?
|
183
|
+
|
184
|
+
iteration = (response["count"].to_i / _items.size.to_f).ceil
|
185
|
+
|
186
|
+
iteration.times do |index|
|
187
|
+
next if index == 0
|
188
|
+
|
189
|
+
options[:offset] += options[:count]
|
190
|
+
_items += (methods.size == 2 ? user.send(methods[0]).send(methods[1], options) : user.send(name, options))["items"]
|
191
|
+
end
|
192
|
+
|
193
|
+
_items
|
194
|
+
end
|
195
|
+
|
196
|
+
def fetch_all_method_items_with_days(name, options)
|
197
|
+
days = options.delete(:days)
|
198
|
+
date_end = options.delete(:date_end)
|
199
|
+
|
200
|
+
methods = name.to_s.split(".")
|
201
|
+
response = methods.size == 2 ? user.send(methods[0]).send(methods[1], options) : user.send(name, options)
|
202
|
+
|
203
|
+
return [] if response.blank? || !response.is_a?(Hash)
|
204
|
+
|
205
|
+
_items = response["items"]
|
206
|
+
return [] if _items.blank?
|
207
|
+
|
208
|
+
if days
|
209
|
+
date = (date_end || Time.now) - days.days
|
210
|
+
iteration = (response["count"].to_i / _items.size.to_f).ceil
|
211
|
+
last_date = _items.last ? Time.at(_items.last["date"].to_i).to_datetime : nil
|
212
|
+
|
213
|
+
iteration.times do |index|
|
214
|
+
next if index == 0
|
215
|
+
|
216
|
+
options[:offset] += options[:count]
|
217
|
+
_items += (methods.size == 2 ? user.send(methods[0]).send(methods[1], options) : user.send(name, options))["items"]
|
218
|
+
|
219
|
+
last_date = _items.last ? Time.at(_items.last["date"].to_i).to_datetime : nil
|
220
|
+
break if last_date.blank? || last_date < date
|
221
|
+
end if !last_date.blank? && last_date > date
|
222
|
+
|
223
|
+
return _items.select { |item| Time.at(item["date"].to_i).to_datetime > date }
|
224
|
+
end
|
225
|
+
|
226
|
+
_items
|
227
|
+
end
|
42
228
|
end
|
43
229
|
|
44
230
|
class Album
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module SocialProfile
|
4
|
+
module Providers
|
5
|
+
class Odnoklassniki < Base
|
6
|
+
|
7
|
+
def picture_url
|
8
|
+
@picture_url ||= begin
|
9
|
+
url = info('image').gsub("photoType=4", "photoType=3")
|
10
|
+
check_url(url)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def profile_url
|
15
|
+
@profile_url ||= begin
|
16
|
+
urls = info('urls')
|
17
|
+
urls.nil? ? nil : urls['Odnoklassniki']
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# 0 - unknown
|
22
|
+
# 1 - female
|
23
|
+
# 2 - male
|
24
|
+
# Возвращаемые значения: 1 - женский, 2 - мужской, 0 - без указания пола.
|
25
|
+
def gender
|
26
|
+
@gender ||= case extra('raw_info')['gender']
|
27
|
+
when 'male' then 2
|
28
|
+
when 'female' then 1
|
29
|
+
else 0
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def birthday
|
34
|
+
@birthday ||= begin
|
35
|
+
Date.strptime(extra('raw_info')['birthday'],'%m/%d/%Y')
|
36
|
+
rescue Exception => e
|
37
|
+
nil
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def city_name
|
42
|
+
@city_name ||= begin
|
43
|
+
location('city')
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def location?
|
48
|
+
raw_info? && extra('raw_info')['location'] && extra('raw_info')['location'].is_a?(Hash)
|
49
|
+
end
|
50
|
+
|
51
|
+
def location(key)
|
52
|
+
if location? && Utils.exists?(extra('raw_info')['location'][key])
|
53
|
+
extra('raw_info')['location'][key]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
protected
|
58
|
+
|
59
|
+
def check_url(url)
|
60
|
+
response = Utils.head(url, :follow_redirects => false)
|
61
|
+
|
62
|
+
if response.code == 302 && response.headers['location']
|
63
|
+
[response.headers['location']].flatten.first
|
64
|
+
else
|
65
|
+
url
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def raw_info?
|
70
|
+
extra('raw_info') && extra('raw_info').is_a?(Hash)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/lib/social_profile.rb
CHANGED
@@ -11,6 +11,7 @@ module SocialProfile
|
|
11
11
|
autoload :Vkontakte, "social_profile/providers/vkontakte"
|
12
12
|
autoload :Twitter, "social_profile/providers/twitter"
|
13
13
|
autoload :Instagram, "social_profile/providers/instagram"
|
14
|
+
autoload :Odnoklassniki, "social_profile/providers/odnoklassniki"
|
14
15
|
end
|
15
16
|
|
16
17
|
module People
|
@@ -27,6 +28,7 @@ module SocialProfile
|
|
27
28
|
when "vkontakte" then Providers::Vkontakte
|
28
29
|
when "twitter" then Providers::Twitter
|
29
30
|
when "instagram" then Providers::Instagram
|
31
|
+
when "odnoklassniki" then Providers::Odnoklassniki
|
30
32
|
else Providers::Base
|
31
33
|
end
|
32
34
|
|
data/social_profile.gemspec
CHANGED
@@ -21,9 +21,9 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.add_development_dependency "bundler", "~> 1.3"
|
22
22
|
spec.add_development_dependency "rake"
|
23
23
|
|
24
|
-
spec.add_dependency "fb_graph"
|
25
|
-
spec.add_dependency "vkontakte"
|
26
|
-
spec.add_dependency "twitter"
|
24
|
+
spec.add_dependency "fb_graph", '~> 2.7.16'
|
25
|
+
spec.add_dependency "vkontakte", '~> 0.0.6'
|
26
|
+
spec.add_dependency "twitter", '~> 5.11.0'
|
27
27
|
spec.add_dependency "httpclient"
|
28
28
|
spec.add_dependency "multi_json"
|
29
29
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
{
|
2
|
+
"data": [
|
3
|
+
{
|
4
|
+
"name": "Sergey Kochergan",
|
5
|
+
"id": "100002162037770"
|
6
|
+
},
|
7
|
+
{
|
8
|
+
"name": "Lyudmila Bublik",
|
9
|
+
"id": "100006720518271"
|
10
|
+
},
|
11
|
+
{
|
12
|
+
"name": "Victoria Zhurbas",
|
13
|
+
"id": "1425672521"
|
14
|
+
},
|
15
|
+
{
|
16
|
+
"name": "Марина Николаева",
|
17
|
+
"id": "100002446576144"
|
18
|
+
},
|
19
|
+
{
|
20
|
+
"name": "Alex Filatov",
|
21
|
+
"id": "1198544135"
|
22
|
+
}
|
23
|
+
],
|
24
|
+
"paging": {
|
25
|
+
"cursors": {
|
26
|
+
"after": "MTE5ODU0NDEzNQ==",
|
27
|
+
"before": "MTAwMDAyMTYyMDM3Nzcw"
|
28
|
+
},
|
29
|
+
"next": "https://graph.facebook.com/v1.0/100000730417342/subscribers?limit=5&after=MTE5ODU0NDEzNQ=="
|
30
|
+
},
|
31
|
+
"summary": {
|
32
|
+
"total_count": 14
|
33
|
+
}
|
34
|
+
}
|
@@ -0,0 +1,35 @@
|
|
1
|
+
{
|
2
|
+
"data": [
|
3
|
+
{
|
4
|
+
"name": "Max Solomianyi",
|
5
|
+
"id": "100000419905855"
|
6
|
+
},
|
7
|
+
{
|
8
|
+
"name": "Олег Гардаш",
|
9
|
+
"id": "100001535481251"
|
10
|
+
},
|
11
|
+
{
|
12
|
+
"name": "Oleg Pavlov",
|
13
|
+
"id": "100004742075897"
|
14
|
+
},
|
15
|
+
{
|
16
|
+
"name": "Тепли Викна",
|
17
|
+
"id": "100003304746675"
|
18
|
+
},
|
19
|
+
{
|
20
|
+
"name": "Rashed Mohammad",
|
21
|
+
"id": "100004427467621"
|
22
|
+
}
|
23
|
+
],
|
24
|
+
"paging": {
|
25
|
+
"cursors": {
|
26
|
+
"after": "MTAwMDA0NDI3NDY3NjIx",
|
27
|
+
"before": "MTAwMDAwNDE5OTA1ODU1"
|
28
|
+
},
|
29
|
+
"previous": "https://graph.facebook.com/v1.0/100000730417342/subscribers?limit=5&before=MTAwMDAwNDE5OTA1ODU1",
|
30
|
+
"next": "https://graph.facebook.com/v1.0/100000730417342/subscribers?limit=5&after=MTAwMDA0NDI3NDY3NjIx"
|
31
|
+
},
|
32
|
+
"summary": {
|
33
|
+
"total_count": 14
|
34
|
+
}
|
35
|
+
}
|
@@ -0,0 +1,26 @@
|
|
1
|
+
{
|
2
|
+
"data": [
|
3
|
+
{
|
4
|
+
"name": "Zyazyaveka Ad Critic",
|
5
|
+
"id": "100001860144695"
|
6
|
+
},
|
7
|
+
{
|
8
|
+
"name": "Aleksandr Mykoliuk",
|
9
|
+
"id": "1043306710"
|
10
|
+
},
|
11
|
+
{
|
12
|
+
"name": "Solmaz Fooladi",
|
13
|
+
"id": "1413023193"
|
14
|
+
}
|
15
|
+
],
|
16
|
+
"paging": {
|
17
|
+
"cursors": {
|
18
|
+
"after": "MTQxMzAyMzE5Mw==",
|
19
|
+
"before": "MTAwMDAxODYwMTQ0Njk1"
|
20
|
+
},
|
21
|
+
"previous": "https://graph.facebook.com/v1.0/100000730417342/subscribers?limit=5&before=MTAwMDAxODYwMTQ0Njk1"
|
22
|
+
},
|
23
|
+
"summary": {
|
24
|
+
"total_count": 14
|
25
|
+
}
|
26
|
+
}
|
@@ -1 +1 @@
|
|
1
|
-
{"id":7505382,"id_str":"7505382","name":"Erik Michaels-Ober","screen_name":"sferik","location":"","description":"May contain forward-looking statements.","url":"https:\/\/t.co\/L2xIBazMPf","entities":{"url":{"urls":[{"url":"https:\/\/t.co\/L2xIBazMPf","expanded_url":"https:\/\/github.com\/sferik","display_url":"github.com\/sferik","indices":[0,23]}]},"description":{"urls":[]}},"protected":false,"followers_count":
|
1
|
+
{"id":7505382,"id_str":"7505382","name":"Erik Michaels-Ober","screen_name":"sferik","location":"","description":"May contain forward-looking statements.","url":"https:\/\/t.co\/L2xIBazMPf","entities":{"url":{"urls":[{"url":"https:\/\/t.co\/L2xIBazMPf","expanded_url":"https:\/\/github.com\/sferik","display_url":"github.com\/sferik","indices":[0,23]}]},"description":{"urls":[]}},"protected":false,"followers_count":69,"friends_count":361,"listed_count":238,"created_at":"Mon Jul 16 12:59:01 +0000 2007","favourites_count":8976,"utc_offset":3600,"time_zone":"Berlin","geo_enabled":true,"verified":false,"statuses_count":13844,"lang":"en","status":{"created_at":"Wed Mar 19 00:50:35 +0000 2014","id":446086297866993665,"id_str":"446086297866993665","text":"RT @AntonWSJ: Okean Elzy, #Ukraine's biggest rock band, performed in Berlin tonight amid many \"Glory to Ukraine!\" chants http:\/\/t.co\/dkIF8X\u2026","source":"\u003ca href=\"http:\/\/itunes.apple.com\/us\/app\/twitter\/id409789998?mt=12\" rel=\"nofollow\"\u003eTwitter for Mac\u003c\/a\u003e","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"geo":null,"coordinates":null,"place":null,"contributors":null,"retweeted_status":{"created_at":"Tue Mar 18 23:56:08 +0000 2014","id":446072592227909632,"id_str":"446072592227909632","text":"Okean Elzy, #Ukraine's biggest rock band, performed in Berlin tonight amid many \"Glory to Ukraine!\" chants http:\/\/t.co\/dkIF8XvFyw","source":"\u003ca href=\"http:\/\/www.apple.com\" rel=\"nofollow\"\u003eiOS\u003c\/a\u003e","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"geo":null,"coordinates":null,"place":null,"contributors":null,"retweet_count":4,"favorite_count":2,"entities":{"hashtags":[{"text":"Ukraine","indices":[12,20]}],"symbols":[],"urls":[],"user_mentions":[],"media":[{"id":446072592047538176,"id_str":"446072592047538176","indices":[107,129],"media_url":"http:\/\/pbs.twimg.com\/media\/BjDEqLkIAAAIpE4.jpg","media_url_https":"https:\/\/pbs.twimg.com\/media\/BjDEqLkIAAAIpE4.jpg","url":"http:\/\/t.co\/dkIF8XvFyw","display_url":"pic.twitter.com\/dkIF8XvFyw","expanded_url":"http:\/\/twitter.com\/AntonWSJ\/status\/446072592227909632\/photo\/1","type":"photo","sizes":{"medium":{"w":600,"h":450,"resize":"fit"},"large":{"w":1024,"h":768,"resize":"fit"},"thumb":{"w":150,"h":150,"resize":"crop"},"small":{"w":340,"h":255,"resize":"fit"}}}]},"favorited":true,"retweeted":true,"possibly_sensitive":false,"lang":"en"},"retweet_count":4,"favorite_count":0,"entities":{"hashtags":[{"text":"Ukraine","indices":[26,34]}],"symbols":[],"urls":[],"user_mentions":[{"screen_name":"AntonWSJ","name":"Anton Troianovski","id":76773876,"id_str":"76773876","indices":[3,12]}],"media":[{"id":446072592047538176,"id_str":"446072592047538176","indices":[139,140],"media_url":"http:\/\/pbs.twimg.com\/media\/BjDEqLkIAAAIpE4.jpg","media_url_https":"https:\/\/pbs.twimg.com\/media\/BjDEqLkIAAAIpE4.jpg","url":"http:\/\/t.co\/dkIF8XvFyw","display_url":"pic.twitter.com\/dkIF8XvFyw","expanded_url":"http:\/\/twitter.com\/AntonWSJ\/status\/446072592227909632\/photo\/1","type":"photo","sizes":{"medium":{"w":600,"h":450,"resize":"fit"},"large":{"w":1024,"h":768,"resize":"fit"},"thumb":{"w":150,"h":150,"resize":"crop"},"small":{"w":340,"h":255,"resize":"fit"}}}]},"favorited":true,"retweeted":true,"possibly_sensitive":false,"lang":"en"},"contributors_enabled":false,"is_translator":false,"is_translation_enabled":false,"profile_background_color":"000000","profile_background_image_url":"http:\/\/pbs.twimg.com\/profile_background_images\/677717672\/bb0b3653dcf0644e344823e0a2eb3382.png","profile_background_image_url_https":"https:\/\/pbs.twimg.com\/profile_background_images\/677717672\/bb0b3653dcf0644e344823e0a2eb3382.png","profile_background_tile":false,"profile_image_url":"http:\/\/pbs.twimg.com\/profile_images\/378800000757402331\/d8dfba561e2e94112a737f17e7d138ca_normal.jpeg","profile_image_url_https":"https:\/\/pbs.twimg.com\/profile_images\/378800000757402331\/d8dfba561e2e94112a737f17e7d138ca_normal.jpeg","profile_banner_url":"https:\/\/pbs.twimg.com\/profile_banners\/7505382\/1385736840","profile_link_color":"0084B4","profile_sidebar_border_color":"000000","profile_sidebar_fill_color":"DDEEF6","profile_text_color":"333333","profile_use_background_image":true,"default_profile":false,"default_profile_image":false,"following":false,"follow_request_sent":false,"notifications":false,"suspended":false,"needs_phone_verification":false}
|