social_profile 0.2.1 → 0.2.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d44aa58dfddf32479ef916e66b88cb18006ddb01
4
- data.tar.gz: 02d418b320701c6378d5b3c773fb017e8a46c369
3
+ metadata.gz: 9ff2a46cb1b8edb78c457fb204d2efac1035b642
4
+ data.tar.gz: e843f72028951caa385e61478566a2eda9ba31ae
5
5
  SHA512:
6
- metadata.gz: ac9db1fcbd22aee01f98b9f67fca013253c461aba73b22989a0fc4b50a19b9d9631183b5ac14b45144294d435c2062e2a73d58614cd33344805229a115e3a614
7
- data.tar.gz: 7f30303b62b4f02700c4fb7832992e9ff7f4289ece4b2e011ef47f45810ecd34ec041a24fadf73d1a09e2aa24cc203c9f8e65f341a4ac61d9b9c6ede20b1c1fc
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] || 500000
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] || 500000
97
- user.subscribers(:limit => limit)
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
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  module SocialProfile
3
- VERSION = "0.2.1"
3
+ VERSION = "0.2.2"
4
4
  end
@@ -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
 
@@ -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":4051,"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}
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}