ft_42 0.0.7 → 0.0.8
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/bin/ft_42 +2 -82
- data/lib/ft_42.rb +269 -0
- data/test/test_ft_42.rb +6 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ca7ec278557eb88fba8fa55ddbb8b4e5f581d614
|
4
|
+
data.tar.gz: 62ea7b026a9c462d7a1c220c8b5e9aa22e44e972
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6a9329990fdf3559f68b696342d158b2be4271374003de5a423ccf6e2080ac069fcacd42231ce0891674e20f64ad749f235c0fb045be3c13a9693ab244422204
|
7
|
+
data.tar.gz: e63f7801fa7d75db446798fb8b09c6c6fead8122ad6d683cf7e00f46c0004cd9762ce0026aa4ce7835674a29f9dd97a6dcd7282bd6d9fecaa129db41d8e49f98
|
data/bin/ft_42
CHANGED
@@ -1,85 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
require "active_support/all"
|
3
|
-
require "action_view"
|
4
|
-
require "pastel"
|
5
|
-
require "oauth2"
|
6
|
-
require "ruby-progressbar"
|
7
|
-
require "pp"
|
8
2
|
|
9
|
-
|
10
|
-
USERNAME = ARGV[0]
|
11
|
-
UID = ENV.fetch("FT42_UID")
|
12
|
-
SECRET = ENV.fetch("FT42_SECRET")
|
3
|
+
require "ft_42"
|
13
4
|
|
14
|
-
|
15
|
-
case true
|
16
|
-
when host.include?("z1") then "Cluster 1"
|
17
|
-
when host.include?("z2") then "Cluster 2"
|
18
|
-
when host.include?("z3") then "Cluster 3"
|
19
|
-
when host.include?("z3") then "Cluster 4"
|
20
|
-
else host
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
# get token
|
25
|
-
client = OAuth2::Client.new(UID, SECRET, site: "https://api.intra.42.fr")
|
26
|
-
token = client.client_credentials.get_token
|
27
|
-
|
28
|
-
# helpers
|
29
|
-
time_ago = Time.current.beginning_of_week.to_s.split(" ")[0...-1].join("T")
|
30
|
-
right_now = Time.current.to_s.split(" ")[0...-1].join("T")
|
31
|
-
|
32
|
-
# Make requests
|
33
|
-
user = token.get("/v2/users/#{USERNAME}", params: { per_page: 100 }).parsed
|
34
|
-
sessions = token.get("/v2/users/#{USERNAME}/locations?range[begin_at]=#{time_ago},#{right_now}", params: { per_page: 100 }).parsed
|
35
|
-
phone = %x(ldapsearch -Q uid=#{USERNAME} | grep mobile).split.last
|
36
|
-
|
37
|
-
# calculate hours
|
38
|
-
duration = 0
|
39
|
-
sessions.each do |session|
|
40
|
-
begin_at = session["begin_at"].to_time
|
41
|
-
end_at = session["end_at"].to_time
|
42
|
-
duration += (end_at - begin_at)
|
43
|
-
end
|
44
|
-
hours = (duration / 60 / 60).round
|
45
|
-
|
46
|
-
# currently working on
|
47
|
-
in_progress = user["projects_users"].select { |project| project["status"] == "in_progress" }.map { |in_prog| in_prog["project"]["name"] }
|
48
|
-
in_progress = ["something, maybe.."] if in_progress.empty?
|
49
|
-
|
50
|
-
# printer
|
51
|
-
pastel = Pastel.new
|
52
|
-
|
53
|
-
puts pastel.bright_green.bold("#{user['first_name']} #{user['last_name']}")
|
54
|
-
|
55
|
-
# is active?
|
56
|
-
active = false
|
57
|
-
sessions.each do |session|
|
58
|
-
if session["begin_at"].to_time - session["end_at"].to_time == -600.0
|
59
|
-
unless active
|
60
|
-
puts "Is #{pastel.bright_green.bold('active')} at " + pastel.bright_green.bold("#{cluster(session['host'])}") + " computer #{session['host']}."
|
61
|
-
end
|
62
|
-
unless session["primary"]
|
63
|
-
puts pastel.red.bold("Warning: Logged in on more than one computer. Please logout from #{session['host']} ASAP.")
|
64
|
-
end
|
65
|
-
active = true
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
unless active
|
70
|
-
puts "Was last active " + pastel.bright_green.bold("#{ActionView::Base.new.time_ago_in_words(sessions.first['end_at'].to_time)} ago") + " at #{pastel.bright_green.bold(cluster(sessions.first['host']))}."
|
71
|
-
end
|
72
|
-
|
73
|
-
puts "Has " + pastel.bright_green.bold("#{hours} #{hours == 1 ? 'hour' : 'hours'}") + " in the clusters this week, starting #{Time.current.beginning_of_week.strftime("%A, %B #{Time.current.beginning_of_week.day.ordinalize}")}. #{'Go to sleep.' if hours > 60}"
|
74
|
-
|
75
|
-
percent_complete = ((hours.to_f / HOURS_NEEDED.to_f) * 100).round
|
76
|
-
if (percent_complete <= 100)
|
77
|
-
progressbar_needed = ProgressBar.create(progress_mark: "█", length: 60, format: "%t: |" + pastel.red("%B") + "| #{hours}/38 hours")
|
78
|
-
percent_complete.times { progressbar_needed.increment }
|
79
|
-
puts progressbar_needed
|
80
|
-
end
|
81
|
-
|
82
|
-
puts "Is working on #{pastel.bright_green.bold(in_progress.to_sentence)}."
|
83
|
-
puts "Is level #{pastel.bright_green.bold(ActiveSupport::NumberHelper.number_to_rounded(user['cursus_users'].select { |cursus| cursus['cursus']['name'] == "42" }.first['level'], precision: 2))}"
|
84
|
-
puts "Has #{pastel.bright_green.bold(ActionView::Base.new.pluralize(user['correction_point'], 'correction point'))}.#{' *grabs pitchfork*' if user['correction_point'] > 6}"
|
85
|
-
puts "You can contact #{user['first_name'].titleize} at #{pastel.bright_green.bold(ActiveSupport::NumberHelper.number_to_phone(phone))}."
|
5
|
+
FT_42.new(*ARGV)
|
data/lib/ft_42.rb
CHANGED
@@ -1,2 +1,271 @@
|
|
1
|
+
require "active_support/all"
|
2
|
+
require "action_view"
|
3
|
+
require "pastel"
|
4
|
+
require "oauth2"
|
5
|
+
require "ruby-progressbar"
|
6
|
+
|
7
|
+
module Constants
|
8
|
+
URL_42 = "https://api.intra.42.fr"
|
9
|
+
UID_42 = ENV.fetch("FT42_UID")
|
10
|
+
SECRET_42 = ENV.fetch("FT42_SECRET")
|
11
|
+
HOURS_NEEDED = 38
|
12
|
+
end
|
13
|
+
|
1
14
|
class FT_42
|
15
|
+
include Constants
|
16
|
+
|
17
|
+
def initialize(*args)
|
18
|
+
ft_42 = Client.new(args.first)
|
19
|
+
user = User.new(ft_42.user)
|
20
|
+
user_sessions = UserSessions.new(ft_42.user_sessions)
|
21
|
+
user_print = UserPrinter.new(user)
|
22
|
+
user_sessions_print = UserSessionsPrinter.new(user_sessions)
|
23
|
+
user_print.all
|
24
|
+
user_sessions_print.all
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class Client
|
29
|
+
attr_reader :username, :token
|
30
|
+
|
31
|
+
def initialize(username)
|
32
|
+
@username = username
|
33
|
+
@token = Token.new.token
|
34
|
+
end
|
35
|
+
|
36
|
+
def user
|
37
|
+
token.get("/v2/users/#{username}", params: { per_page: 100 }).parsed
|
38
|
+
end
|
39
|
+
|
40
|
+
def user_sessions
|
41
|
+
token.get("/v2/users/#{username}/locations?range[begin_at]=#{time_ago},#{right_now}", params: { per_page: 100 }).parsed
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def time_ago
|
47
|
+
Time.current.beginning_of_week.to_s.split(" ")[0...-1].join("T")
|
48
|
+
end
|
49
|
+
|
50
|
+
def right_now
|
51
|
+
Time.current.to_s.split(" ")[0...-1].join("T")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class Token
|
56
|
+
include Constants
|
57
|
+
|
58
|
+
attr_reader :token
|
59
|
+
|
60
|
+
def initialize
|
61
|
+
client = OAuth2::Client.new(UID_42, SECRET_42, site: URL_42)
|
62
|
+
@token = client.client_credentials.get_token
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class User
|
67
|
+
attr_reader :user
|
68
|
+
|
69
|
+
def initialize(user_response)
|
70
|
+
@user = user_response
|
71
|
+
end
|
72
|
+
|
73
|
+
def current_projects
|
74
|
+
if projects_in_progress.empty?
|
75
|
+
return ["something, maybe..."]
|
76
|
+
else
|
77
|
+
return projects_in_progress.map { |in_prog| in_prog["project"]["name"] }
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def first_name
|
82
|
+
user["first_name"]
|
83
|
+
end
|
84
|
+
|
85
|
+
def last_name
|
86
|
+
user["last_name"]
|
87
|
+
end
|
88
|
+
|
89
|
+
def full_name
|
90
|
+
"#{first_name} #{last_name}"
|
91
|
+
end
|
92
|
+
|
93
|
+
def correction_points
|
94
|
+
user["correction_point"]
|
95
|
+
end
|
96
|
+
|
97
|
+
def level
|
98
|
+
cursus("42")["level"]
|
99
|
+
end
|
100
|
+
|
101
|
+
def phone
|
102
|
+
%x(ldapsearch -Q uid=#{username} | grep mobile).split.last
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
|
107
|
+
def cursus(name)
|
108
|
+
user['cursus_users'].select { |cursus| cursus['cursus']['name'] == name }.first
|
109
|
+
end
|
110
|
+
|
111
|
+
def projects_in_progress
|
112
|
+
user["projects_users"].select { |project| project["status"] == "in_progress" }
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
class Session
|
117
|
+
attr_reader :session
|
118
|
+
|
119
|
+
def initialize(session)
|
120
|
+
@session = session
|
121
|
+
end
|
122
|
+
|
123
|
+
def begin_at
|
124
|
+
session["begin_at"].to_time
|
125
|
+
end
|
126
|
+
|
127
|
+
def end_at
|
128
|
+
session["end_at"].to_time
|
129
|
+
end
|
130
|
+
|
131
|
+
def host
|
132
|
+
session["host"]
|
133
|
+
end
|
134
|
+
|
135
|
+
def primary?
|
136
|
+
session["primary"]
|
137
|
+
end
|
138
|
+
|
139
|
+
def duration
|
140
|
+
end_at - begin_at
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
class UserSessions
|
145
|
+
attr_reader :user_sessions
|
146
|
+
|
147
|
+
def initialize(user_sessions_response)
|
148
|
+
@user_sessions = user_sessions_response
|
149
|
+
end
|
150
|
+
|
151
|
+
def sessions
|
152
|
+
user_sessions.map { |session| Session.new(session) }
|
153
|
+
end
|
154
|
+
|
155
|
+
def total_hours_this_week
|
156
|
+
total_duration = 0
|
157
|
+
sessions.each do |session|
|
158
|
+
total_duration += session.duration
|
159
|
+
end
|
160
|
+
(total_duration / 60 / 60).round
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
class UserPrinter
|
165
|
+
attr_reader :pastel, :user
|
166
|
+
|
167
|
+
def initialize(user)
|
168
|
+
@pastel = Pastel.new
|
169
|
+
@user = user
|
170
|
+
end
|
171
|
+
|
172
|
+
def all
|
173
|
+
name
|
174
|
+
current_projects
|
175
|
+
level
|
176
|
+
correction_points
|
177
|
+
end
|
178
|
+
|
179
|
+
def name
|
180
|
+
puts highlight(user.full_name)
|
181
|
+
end
|
182
|
+
|
183
|
+
def current_projects
|
184
|
+
puts "Is working on #{highlight(user.current_projects.to_sentence)}."
|
185
|
+
end
|
186
|
+
|
187
|
+
def level
|
188
|
+
puts "Is level #{highlight(ActiveSupport::NumberHelper.number_to_rounded(user.level, precision: 2))}"
|
189
|
+
end
|
190
|
+
|
191
|
+
def correction_points
|
192
|
+
print "Has #{highlight(ActionView::Base.new.pluralize(user.correction_points, 'correction point'))}."
|
193
|
+
grabs_pitchfork if user.correction_points > 6
|
194
|
+
puts
|
195
|
+
end
|
196
|
+
|
197
|
+
def contact
|
198
|
+
puts "You can contact #{user.first_name.titleize} at #{highlight(ActiveSupport::NumberHelper.number_to_phone(user.phone))}."
|
199
|
+
end
|
200
|
+
|
201
|
+
private
|
202
|
+
|
203
|
+
def highlight(string)
|
204
|
+
pastel.bright_green.bold(string)
|
205
|
+
end
|
206
|
+
|
207
|
+
def grabs_pitchfork
|
208
|
+
print " *grabs pitchfork*"
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
class UserSessionsPrinter
|
213
|
+
include Constants
|
214
|
+
|
215
|
+
attr_reader :pastel, :user_sessions
|
216
|
+
|
217
|
+
def initialize(user_sessions)
|
218
|
+
@pastel = Pastel.new
|
219
|
+
@user_sessions = user_sessions
|
220
|
+
end
|
221
|
+
|
222
|
+
def all
|
223
|
+
unless user_sessions.sessions.empty?
|
224
|
+
active = false
|
225
|
+
user_sessions.sessions.each do |session|
|
226
|
+
if session.end_at - session.begin_at == 600.0
|
227
|
+
unless active
|
228
|
+
puts "Is #{highlight('active')} at " + highlight("#{cluster(session.host)}") + " computer #{session.host}."
|
229
|
+
end
|
230
|
+
unless session.primary?
|
231
|
+
puts pastel.red.bold("Warning: Logged in on more than one computer. Please logout from #{session.host} ASAP.")
|
232
|
+
end
|
233
|
+
active = true
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
unless active
|
238
|
+
puts "Was last active " + highlight("#{ActionView::Base.new.time_ago_in_words(user_sessions.sessions.first.end_at)} ago") + " at #{highlight(cluster(user_sessions.sessions.first.host))}."
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
puts "Has " + highlight("#{hours} #{hours == 1 ? 'hour' : 'hours'}") + " in the clusters this week, starting #{Time.current.beginning_of_week.strftime("%A, %B #{Time.current.beginning_of_week.day.ordinalize}")}. #{'Go to sleep.' if hours > 60}"
|
243
|
+
|
244
|
+
percent_complete = ((hours.to_f / HOURS_NEEDED.to_f) * 100).round
|
245
|
+
if (percent_complete <= 100)
|
246
|
+
progressbar_needed = ProgressBar.create(progress_mark: "█", length: 60, format: "%t: |" + pastel.red("%B") + "| #{hours}/38 hours")
|
247
|
+
percent_complete.times { progressbar_needed.increment }
|
248
|
+
puts progressbar_needed
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
private
|
253
|
+
|
254
|
+
def hours
|
255
|
+
user_sessions.total_hours_this_week
|
256
|
+
end
|
257
|
+
|
258
|
+
def highlight(string)
|
259
|
+
pastel.bright_green.bold(string)
|
260
|
+
end
|
261
|
+
|
262
|
+
def cluster(host)
|
263
|
+
case true
|
264
|
+
when host.include?("z1") then "Cluster 1"
|
265
|
+
when host.include?("z2") then "Cluster 2"
|
266
|
+
when host.include?("z3") then "Cluster 3"
|
267
|
+
when host.include?("z3") then "Cluster 4"
|
268
|
+
else host
|
269
|
+
end
|
270
|
+
end
|
2
271
|
end
|
data/test/test_ft_42.rb
ADDED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ft_42
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matias Fernandez
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-11-
|
11
|
+
date: 2016-11-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -75,6 +75,7 @@ extra_rdoc_files: []
|
|
75
75
|
files:
|
76
76
|
- lib/ft_42.rb
|
77
77
|
- bin/ft_42
|
78
|
+
- test/test_ft_42.rb
|
78
79
|
homepage: http://rubygems.org/gems/ft_42
|
79
80
|
licenses:
|
80
81
|
- MIT
|