rpw 1.1.0 → 1.2.0
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/.github/workflows/test.yml +2 -2
- data/Gemfile.lock +1 -1
- data/HISTORY.md +5 -0
- data/lib/rpw/README.md +18 -16
- data/lib/rpw/cli.rb +182 -11
- data/lib/rpw/cli/key.rb +4 -2
- data/lib/rpw/cli/sub_command_base.rb +0 -12
- data/lib/rpw/client.rb +15 -34
- data/lib/rpw/version.rb +1 -1
- metadata +1 -3
- data/lib/rpw/cli/lesson.rb +0 -129
- data/lib/rpw/cli/progress.rb +0 -38
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c4c79a03ffb13bfdd6fd37581cdca30aa3a69712608add26105f51b130b15fcb
|
4
|
+
data.tar.gz: '05079633b4d192a7654dea1f82972ecb735ea634de59c5e83bde843eec73ef42'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f81567fe95bda4102cc1109e8f643043ee9dcb58d0fc81c1c9faee34ff91fcc3ba3d7265f718c473a19eafbdcf852801c6bea803ddf49c7ad74280f8a85cd3dc
|
7
|
+
data.tar.gz: 66fb292f109656d91d97166733ba21f095d0c7f1cfd06a82e580ab87c8b4bb2d28b03eb95dcb02c32ca5eb4a7e2d379a04afa5b9ae419511c927ea9755c1f877
|
data/.github/workflows/test.yml
CHANGED
@@ -20,7 +20,7 @@ jobs:
|
|
20
20
|
fail-fast: true
|
21
21
|
matrix:
|
22
22
|
os: [ ubuntu-20.04, macos-10.15, windows-2019 ]
|
23
|
-
ruby: [ 2.
|
23
|
+
ruby: [ 2.6, 2.7, head ]
|
24
24
|
|
25
25
|
steps:
|
26
26
|
- name: repo checkout
|
@@ -33,7 +33,7 @@ jobs:
|
|
33
33
|
|
34
34
|
- name: bundle install
|
35
35
|
run: |
|
36
|
-
bundle install --jobs 4 --retry 3
|
36
|
+
gem install bundler && bundle install --jobs 4 --retry 3
|
37
37
|
|
38
38
|
- name: standardrb
|
39
39
|
run: bundle exec standardrb
|
data/Gemfile.lock
CHANGED
data/HISTORY.md
CHANGED
data/lib/rpw/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
## Installation Requirements
|
2
2
|
|
3
|
-
This client assumes you're using Ruby 2.
|
3
|
+
This client assumes you're using Ruby 2.6 or later.
|
4
4
|
|
5
5
|
This client assumes you have `tar` installed and available on your PATH.
|
6
6
|
|
@@ -11,6 +11,11 @@ The way that the client opens files (using `open` or `xdg-open` depending on pla
|
|
11
11
|
|
12
12
|
## Slack Invite
|
13
13
|
|
14
|
+
The Slack channel is your best resource for questions about Rails Performance
|
15
|
+
or other material in the workshop. Nate is almost always monitoring that channel.
|
16
|
+
|
17
|
+
If you encounter a **bug or other software problem**, please email support@speedshop.co.
|
18
|
+
|
14
19
|
If you purchased the Workshop yourself, you will receive a Slack channel invitation
|
15
20
|
shortly. If you are attending the Workshop as part of a group and your license key
|
16
21
|
was provided to you, you need to register your key to get an invite:
|
@@ -21,33 +26,30 @@ $ rpw key register [YOUR_EMAIL_ADDRESS]
|
|
21
26
|
|
22
27
|
Please note you can only register your key once.
|
23
28
|
|
24
|
-
The Slack channel is your best resource for questions about Rails Performance
|
25
|
-
or other material in the workshop. Nate is almost always monitoring that channel.
|
26
|
-
|
27
|
-
If you encounter a **bug or other software problem**, please email support@speedshop.co.
|
28
|
-
|
29
29
|
## Important Commands
|
30
30
|
|
31
31
|
Here are some important commands for you to know:
|
32
32
|
|
33
33
|
```
|
34
|
-
$ rpw
|
35
|
-
$ rpw
|
36
|
-
$ rpw
|
37
|
-
$ rpw
|
38
|
-
$ rpw
|
39
|
-
$ rpw
|
34
|
+
$ rpw next | Proceed to the next part of the workshop.
|
35
|
+
$ rpw complete | Mark current lesson as complete.
|
36
|
+
$ rpw list | List all workshop lessons. Shows progress.
|
37
|
+
$ rpw download | Download all lessons. Useful for offline access.
|
38
|
+
$ rpw show | Show any particular workshop lesson.
|
39
|
+
$ rpw current | Opens the current lesson.
|
40
40
|
```
|
41
41
|
|
42
|
-
Generally, you'll just be doing a lot of `$ rpw
|
42
|
+
Generally, you'll just be doing a lot of `$ rpw next`! It's basically the same thing as `$ rpw complete && rpw show`.
|
43
|
+
|
44
|
+
#### --no-open
|
43
45
|
|
44
|
-
By default, `$ rpw
|
45
|
-
either don't like this, or for some reason it doesn't work, use `$ rpw
|
46
|
+
By default, `$ rpw next` (and `$ rpw show` and `$ rpw current`) will try to open the content it downloads. If you
|
47
|
+
either don't like this, or for some reason it doesn't work, use `$ rpw next --no-open`.
|
46
48
|
|
47
49
|
## Working Offline
|
48
50
|
|
49
51
|
By default, the course will download each piece of content as you progress through
|
50
|
-
the course. However, you can use `rpw
|
52
|
+
the course. However, you can use `rpw download` to download all content
|
51
53
|
at once, and complete the workshop entirely offline.
|
52
54
|
|
53
55
|
Videos in this workshop are generally about 100MB each, which means the entire
|
data/lib/rpw/cli.rb
CHANGED
@@ -4,8 +4,6 @@ require "rpw"
|
|
4
4
|
require "rpw/cli/bannerlord"
|
5
5
|
require "rpw/cli/sub_command_base"
|
6
6
|
require "rpw/cli/key"
|
7
|
-
require "rpw/cli/lesson"
|
8
|
-
require "rpw/cli/progress"
|
9
7
|
require "cli/ui"
|
10
8
|
|
11
9
|
CLI::UI::StdoutRouter.enable
|
@@ -16,10 +14,6 @@ module RPW
|
|
16
14
|
|
17
15
|
desc "key register [EMAIL_ADDRESS]", "Change email registered w/Speedshop"
|
18
16
|
subcommand "key", Key
|
19
|
-
desc "lesson [SUBCOMMAND]", "View and download lessons"
|
20
|
-
subcommand "lesson", Lesson
|
21
|
-
desc "progress [SUBCOMMAND]", "View and set progress"
|
22
|
-
subcommand "progress", Progress
|
23
17
|
|
24
18
|
def self.exit_on_failure?
|
25
19
|
true
|
@@ -60,13 +54,137 @@ module RPW
|
|
60
54
|
exit(0)
|
61
55
|
end
|
62
56
|
|
63
|
-
|
57
|
+
say ""
|
64
58
|
say "Successfully authenticated with the RPW server and saved your key."
|
65
|
-
|
59
|
+
say ""
|
66
60
|
say "Setup complete!"
|
67
|
-
|
68
|
-
say "To learn how to use this command-line client, consult ./README.md,
|
69
|
-
say "
|
61
|
+
say ""
|
62
|
+
say "To learn how to use this command-line client, consult ./README.md,"
|
63
|
+
say "which we just created."
|
64
|
+
say ""
|
65
|
+
say "Once you've read that and you're ready to get going: $ rpw next"
|
66
|
+
end
|
67
|
+
|
68
|
+
desc "next", "Proceed to the next lesson of the workshop"
|
69
|
+
option :"no-open", type: :boolean
|
70
|
+
def next
|
71
|
+
exit_with_no_key
|
72
|
+
content = client.next
|
73
|
+
|
74
|
+
if content.nil?
|
75
|
+
RPW::CLI.new.print_banner
|
76
|
+
say "Congratulations!"
|
77
|
+
say "You have completed the Rails Performance Workshop."
|
78
|
+
exit(0)
|
79
|
+
end
|
80
|
+
|
81
|
+
say "Proceeding to next lesson: #{content["title"]}"
|
82
|
+
client.download_and_extract(content)
|
83
|
+
client.complete(content["position"])
|
84
|
+
display_content(content, !options[:"no-open"])
|
85
|
+
end
|
86
|
+
|
87
|
+
desc "current", "Open the current lesson"
|
88
|
+
option :"no-open", type: :boolean
|
89
|
+
def current
|
90
|
+
exit_with_no_key
|
91
|
+
content = client.current
|
92
|
+
say "Opening: #{content["title"]}"
|
93
|
+
client.download_and_extract(content)
|
94
|
+
display_content(content, !options[:"no-open"])
|
95
|
+
end
|
96
|
+
|
97
|
+
desc "complete", "Mark the current lesson as complete"
|
98
|
+
def complete
|
99
|
+
say "Marked current lesson as complete"
|
100
|
+
client.complete(nil)
|
101
|
+
end
|
102
|
+
|
103
|
+
desc "list", "Show all available workshop lessons"
|
104
|
+
def list
|
105
|
+
::CLI::UI::Frame.open("{{*}} {{bold:All Lessons}}", color: :green)
|
106
|
+
|
107
|
+
frame_open = false
|
108
|
+
client.list.each do |lesson|
|
109
|
+
if lesson["title"].start_with?("Section")
|
110
|
+
::CLI::UI::Frame.close(nil) if frame_open
|
111
|
+
::CLI::UI::Frame.open(lesson["title"])
|
112
|
+
frame_open = true
|
113
|
+
next
|
114
|
+
end
|
115
|
+
|
116
|
+
no_data = client.send(:client_data)["completed"].nil?
|
117
|
+
completed = client.send(:client_data)["completed"]&.include?(lesson["position"])
|
118
|
+
|
119
|
+
str = if no_data
|
120
|
+
""
|
121
|
+
elsif completed
|
122
|
+
"\u{2705} "
|
123
|
+
else
|
124
|
+
"\u{274C} "
|
125
|
+
end
|
126
|
+
|
127
|
+
case lesson["style"]
|
128
|
+
when "video"
|
129
|
+
puts str + ::CLI::UI.fmt("{{red:#{lesson["title"]}}}")
|
130
|
+
when "quiz"
|
131
|
+
# puts ::CLI::UI.fmt "{{green:#{" " + lesson["title"]}}}"
|
132
|
+
when "lab"
|
133
|
+
puts str + ::CLI::UI.fmt("{{yellow:#{" " + lesson["title"]}}}")
|
134
|
+
when "text"
|
135
|
+
puts str + ::CLI::UI.fmt("{{magenta:#{" " + lesson["title"]}}}")
|
136
|
+
else
|
137
|
+
puts str + ::CLI::UI.fmt("{{magenta:#{" " + lesson["title"]}}}")
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
::CLI::UI::Frame.close(nil)
|
142
|
+
::CLI::UI::Frame.close(nil, color: :green)
|
143
|
+
end
|
144
|
+
|
145
|
+
desc "download", "Download all workshop contents"
|
146
|
+
def download
|
147
|
+
exit_with_no_key
|
148
|
+
total = client.list.size
|
149
|
+
client.list.each do |content|
|
150
|
+
current = client.list.index(content) + 1
|
151
|
+
puts "Downloading #{content["title"]} (#{current}/#{total})"
|
152
|
+
client.download_and_extract(content)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
desc "show", "Show any individal workshop lesson"
|
157
|
+
option :"no-open", type: :boolean
|
158
|
+
def show
|
159
|
+
exit_with_no_key
|
160
|
+
title = ::CLI::UI::Prompt.ask(
|
161
|
+
"Which lesson would you like to view?",
|
162
|
+
options: client.list.reject { |l| l["title"] == "Quiz" }.map { |l| " " * l["indent"] + l["title"] }
|
163
|
+
)
|
164
|
+
title.strip!
|
165
|
+
content_order = client.list.find { |l| l["title"] == title }["position"]
|
166
|
+
content = client.show(content_order)
|
167
|
+
client.download_and_extract(content)
|
168
|
+
display_content(content, !options[:"no-open"])
|
169
|
+
end
|
170
|
+
|
171
|
+
desc "set_progress", "Set current lesson to a particular lesson"
|
172
|
+
def set_progress
|
173
|
+
title = ::CLI::UI::Prompt.ask(
|
174
|
+
"Which lesson would you like to set your progress to? All prior lessons will be marked complete",
|
175
|
+
options: client.list.reject { |l| l["title"] == "Quiz" }.map { |l| " " * l["indent"] + l["title"] }
|
176
|
+
)
|
177
|
+
title.strip!
|
178
|
+
content_order = client.list.find { |l| l["title"] == title }["position"]
|
179
|
+
content = client.set_progress(content_order, all_prior: true)
|
180
|
+
say "Setting current progress to #{content.last["title"]}"
|
181
|
+
end
|
182
|
+
|
183
|
+
desc "reset", "Erase all progress and start over"
|
184
|
+
def reset
|
185
|
+
return unless ::CLI::UI.confirm("Are you sure you want to erase all of your progress?", default: false)
|
186
|
+
say "Resetting progress."
|
187
|
+
client.set_progress(nil)
|
70
188
|
end
|
71
189
|
|
72
190
|
no_commands do
|
@@ -77,10 +195,63 @@ module RPW
|
|
77
195
|
|
78
196
|
private
|
79
197
|
|
198
|
+
def exit_with_no_key
|
199
|
+
unless client.setup?
|
200
|
+
say "You have not yet set up the client. Run $ rpw start"
|
201
|
+
exit(1)
|
202
|
+
end
|
203
|
+
unless client.directories_ready?
|
204
|
+
say "You are not in your workshop scratch directory, or you have not yet"
|
205
|
+
say "set up the client. Change directory or run $ rpw start"
|
206
|
+
exit(1)
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
80
210
|
def client
|
81
211
|
@client ||= RPW::Client.new
|
82
212
|
end
|
83
213
|
|
214
|
+
def display_content(content, open_after)
|
215
|
+
openable = false
|
216
|
+
case content["style"]
|
217
|
+
when "video"
|
218
|
+
location = "video/#{content["s3_key"]}"
|
219
|
+
openable = true
|
220
|
+
when "quiz"
|
221
|
+
Quiz.start(["give_quiz", "quiz/" + content["s3_key"]])
|
222
|
+
when "lab"
|
223
|
+
location = "lab/#{content["s3_key"][0..-8]}"
|
224
|
+
openable = true
|
225
|
+
when "text"
|
226
|
+
location = "text/#{content["s3_key"]}"
|
227
|
+
openable = true
|
228
|
+
when "cgrp"
|
229
|
+
say "The Complete Guide to Rails Performance has been downloaded and extracted to the ./cgrp directory."
|
230
|
+
say "All source code for the CGRP is in the src directory, PDF and other compiled formats are in the release directory."
|
231
|
+
say "You can check it out now, or to continue: $ rpw next "
|
232
|
+
end
|
233
|
+
if location
|
234
|
+
if openable && !open_after
|
235
|
+
say "Download complete. Open with: $ #{open_command} #{location}"
|
236
|
+
elsif open_after && openable
|
237
|
+
exec "#{open_command} #{location}"
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
require "rbconfig"
|
243
|
+
def open_command
|
244
|
+
host_os = RbConfig::CONFIG["host_os"]
|
245
|
+
case host_os
|
246
|
+
when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
|
247
|
+
"start"
|
248
|
+
when /darwin|mac os/
|
249
|
+
"open"
|
250
|
+
else
|
251
|
+
"xdg-open"
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
84
255
|
def warn_if_already_started
|
85
256
|
return unless client.setup?
|
86
257
|
exit(0) unless ::CLI::UI.confirm "You have already started the workshop. Continuing "\
|
data/lib/rpw/cli/key.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
module RPW
|
2
2
|
class Key < SubCommandBase
|
3
|
-
class_before :exit_with_no_key
|
4
|
-
|
5
3
|
desc "register [EMAIL_ADDRESS]", "Change email registered with Speedshop. One-time only."
|
6
4
|
def register(email)
|
5
|
+
unless client.setup?
|
6
|
+
say "You have not yet set up the client. Run $ rpw start"
|
7
|
+
exit(1)
|
8
|
+
end
|
7
9
|
if client.register_email(email)
|
8
10
|
say "Key registered with #{email}. You should receive a Slack invite soon."
|
9
11
|
else
|
@@ -13,18 +13,6 @@ module RPW
|
|
13
13
|
def client
|
14
14
|
@client ||= RPW::Client.new
|
15
15
|
end
|
16
|
-
|
17
|
-
def exit_with_no_key
|
18
|
-
unless client.setup?
|
19
|
-
say "You have not yet set up the client. Run $ rpw start"
|
20
|
-
exit(1)
|
21
|
-
end
|
22
|
-
unless client.directories_ready?
|
23
|
-
say "You are not in your workshop scratch directory, or you have not yet"
|
24
|
-
say "set up the client. Change directory or run $ rpw start"
|
25
|
-
exit(1)
|
26
|
-
end
|
27
|
-
end
|
28
16
|
end
|
29
17
|
end
|
30
18
|
end
|
data/lib/rpw/client.rb
CHANGED
@@ -25,6 +25,11 @@ module RPW
|
|
25
25
|
list.sort_by { |c| c["position"] }.find { |c| c["position"] > current_position }
|
26
26
|
end
|
27
27
|
|
28
|
+
def current
|
29
|
+
return list.first unless client_data["completed"]
|
30
|
+
list.sort_by { |c| c["position"] }.find { |c| c["position"] == current_position }
|
31
|
+
end
|
32
|
+
|
28
33
|
def list
|
29
34
|
@list ||= begin
|
30
35
|
if client_data["content_cache_generated"] &&
|
@@ -75,22 +80,17 @@ module RPW
|
|
75
80
|
end
|
76
81
|
end
|
77
82
|
|
78
|
-
def
|
79
|
-
completed_lessons = client_data["completed"] || []
|
80
|
-
{
|
81
|
-
completed: completed_lessons.size,
|
82
|
-
total: list.size,
|
83
|
-
current_lesson: list.find { |c| c["position"] == current_position },
|
84
|
-
sections: chart_section_progress(list, completed_lessons)
|
85
|
-
}
|
86
|
-
end
|
87
|
-
|
88
|
-
def set_progress(pos)
|
83
|
+
def set_progress(pos, all_prior: false)
|
89
84
|
client_data["completed"] = [] && return if pos.nil?
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
85
|
+
if all_prior
|
86
|
+
lessons = list.select { |l| l["position"] <= pos }
|
87
|
+
client_data["completed"] = lessons.map { |l| l["position"] }
|
88
|
+
lessons
|
89
|
+
else
|
90
|
+
lesson = list.find { |l| l["position"] == pos }
|
91
|
+
client_data["completed"] += [pos]
|
92
|
+
lesson
|
93
|
+
end
|
94
94
|
end
|
95
95
|
|
96
96
|
def latest_version?
|
@@ -146,25 +146,6 @@ module RPW
|
|
146
146
|
@current_position ||= client_data["completed"]&.last || 0
|
147
147
|
end
|
148
148
|
|
149
|
-
def chart_section_progress(contents, completed)
|
150
|
-
contents.group_by { |c| c["position"] / 100 }
|
151
|
-
.each_with_object([]) do |(_, c), memo|
|
152
|
-
completed_str = c.map { |l|
|
153
|
-
if l["position"] == current_position
|
154
|
-
"O"
|
155
|
-
elsif completed.include?(l["position"])
|
156
|
-
"X"
|
157
|
-
else
|
158
|
-
"."
|
159
|
-
end
|
160
|
-
}.join
|
161
|
-
memo << {
|
162
|
-
title: c[0]["title"],
|
163
|
-
progress: completed_str
|
164
|
-
}
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
149
|
def client_data
|
169
150
|
@client_data ||= ClientData.new
|
170
151
|
end
|
data/lib/rpw/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rpw
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nate Berkopec
|
@@ -90,8 +90,6 @@ files:
|
|
90
90
|
- lib/rpw/cli.rb
|
91
91
|
- lib/rpw/cli/bannerlord.rb
|
92
92
|
- lib/rpw/cli/key.rb
|
93
|
-
- lib/rpw/cli/lesson.rb
|
94
|
-
- lib/rpw/cli/progress.rb
|
95
93
|
- lib/rpw/cli/quiz.rb
|
96
94
|
- lib/rpw/cli/sub_command_base.rb
|
97
95
|
- lib/rpw/client.rb
|
data/lib/rpw/cli/lesson.rb
DELETED
@@ -1,129 +0,0 @@
|
|
1
|
-
module RPW
|
2
|
-
class Lesson < SubCommandBase
|
3
|
-
desc "next", "Proceed to the next lesson of the workshop"
|
4
|
-
option :"no-open"
|
5
|
-
def next
|
6
|
-
exit_with_no_key
|
7
|
-
say "Proceeding to next lesson..."
|
8
|
-
content = client.next
|
9
|
-
|
10
|
-
if content.nil?
|
11
|
-
RPW::CLI.new.print_banner
|
12
|
-
say "Congratulations!"
|
13
|
-
say "You have completed the Rails Performance Workshop."
|
14
|
-
exit(0)
|
15
|
-
end
|
16
|
-
|
17
|
-
client.download_and_extract(content)
|
18
|
-
client.complete(content["position"])
|
19
|
-
display_content(content, !options[:"no-open"])
|
20
|
-
end
|
21
|
-
|
22
|
-
desc "complete", "Mark the current lesson as complete"
|
23
|
-
def complete
|
24
|
-
say "Marked current lesson as complete"
|
25
|
-
client.complete(nil)
|
26
|
-
end
|
27
|
-
|
28
|
-
desc "list", "Show all available workshop lessons"
|
29
|
-
def list
|
30
|
-
::CLI::UI::Frame.open("{{*}} {{bold:All Lessons}}", color: :green)
|
31
|
-
|
32
|
-
frame_open = false
|
33
|
-
client.list.each do |lesson|
|
34
|
-
if lesson["title"].start_with?("Section")
|
35
|
-
::CLI::UI::Frame.close(nil) if frame_open
|
36
|
-
::CLI::UI::Frame.open(lesson["title"])
|
37
|
-
frame_open = true
|
38
|
-
next
|
39
|
-
end
|
40
|
-
|
41
|
-
case lesson["style"]
|
42
|
-
when "video"
|
43
|
-
puts ::CLI::UI.fmt "{{red:#{lesson["title"]}}}"
|
44
|
-
when "quiz"
|
45
|
-
# puts ::CLI::UI.fmt "{{green:#{" " + lesson["title"]}}}"
|
46
|
-
when "lab"
|
47
|
-
puts ::CLI::UI.fmt "{{yellow:#{" " + lesson["title"]}}}"
|
48
|
-
when "text"
|
49
|
-
puts ::CLI::UI.fmt "{{magenta:#{" " + lesson["title"]}}}"
|
50
|
-
else
|
51
|
-
puts ::CLI::UI.fmt "{{magenta:#{" " + lesson["title"]}}}"
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
::CLI::UI::Frame.close(nil)
|
56
|
-
::CLI::UI::Frame.close(nil, color: :green)
|
57
|
-
end
|
58
|
-
|
59
|
-
desc "download", "Download all workshop contents"
|
60
|
-
def download
|
61
|
-
exit_with_no_key
|
62
|
-
total = client.list.size
|
63
|
-
client.list.each do |content|
|
64
|
-
current = client.list.index(content)
|
65
|
-
puts "Downloading #{content["title"]} (#{current}/#{total})"
|
66
|
-
client.download_and_extract(content)
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
desc "show", "Show any individal workshop lesson"
|
71
|
-
option :"no-open"
|
72
|
-
def show
|
73
|
-
exit_with_no_key
|
74
|
-
title = ::CLI::UI::Prompt.ask(
|
75
|
-
"Which lesson would you like to view?",
|
76
|
-
options: client.list.reject { |l| l["title"] == "Quiz" }.map { |l| " " * l["indent"] + l["title"] }
|
77
|
-
)
|
78
|
-
title.strip!
|
79
|
-
content_order = client.list.find { |l| l["title"] == title }["position"]
|
80
|
-
content = client.show(content_order)
|
81
|
-
client.download_and_extract(content)
|
82
|
-
display_content(content, !options[:"no-open"])
|
83
|
-
end
|
84
|
-
|
85
|
-
private
|
86
|
-
|
87
|
-
def display_content(content, open_after)
|
88
|
-
say "Current Lesson: #{content["title"]}"
|
89
|
-
openable = false
|
90
|
-
case content["style"]
|
91
|
-
when "video"
|
92
|
-
location = "video/#{content["s3_key"]}"
|
93
|
-
openable = true
|
94
|
-
when "quiz"
|
95
|
-
Quiz.start(["give_quiz", "quiz/" + content["s3_key"]])
|
96
|
-
when "lab"
|
97
|
-
location = "lab/#{content["s3_key"][0..-8]}"
|
98
|
-
openable = true
|
99
|
-
when "text"
|
100
|
-
location = "text/#{content["s3_key"]}"
|
101
|
-
openable = true
|
102
|
-
when "cgrp"
|
103
|
-
say "The Complete Guide to Rails Performance has been downloaded and extracted to the ./cgrp directory."
|
104
|
-
say "All source code for the CGRP is in the src directory, PDF and other compiled formats are in the release directory."
|
105
|
-
say "You can check it out now, or to continue: $ rpw lesson next "
|
106
|
-
end
|
107
|
-
if location
|
108
|
-
if openable && !open_after
|
109
|
-
say "Download complete. Open with: $ #{open_command} #{location}"
|
110
|
-
elsif open_after && openable
|
111
|
-
exec "#{open_command} #{location}"
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
require "rbconfig"
|
117
|
-
def open_command
|
118
|
-
host_os = RbConfig::CONFIG["host_os"]
|
119
|
-
case host_os
|
120
|
-
when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
|
121
|
-
"start"
|
122
|
-
when /darwin|mac os/
|
123
|
-
"open"
|
124
|
-
else
|
125
|
-
"xdg-open"
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
129
|
-
end
|
data/lib/rpw/cli/progress.rb
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
module RPW
|
2
|
-
class Progress < SubCommandBase
|
3
|
-
desc "set [LESSON]", "Set current lesson to a particular lesson"
|
4
|
-
def set(pos)
|
5
|
-
lesson = client.set_progress(pos.to_i)
|
6
|
-
say "Set current progress to #{lesson["title"]}"
|
7
|
-
end
|
8
|
-
|
9
|
-
desc "reset", "Erase all progress and start over"
|
10
|
-
def reset
|
11
|
-
return unless ::CLI::UI.confirm("Are you sure you want to erase all of your progress?", default: false)
|
12
|
-
say "Resetting progress."
|
13
|
-
client.set_progress(nil)
|
14
|
-
end
|
15
|
-
|
16
|
-
desc "show", "Show current workshop progress"
|
17
|
-
def show
|
18
|
-
data = client.progress
|
19
|
-
::CLI::UI::Frame.open("The Rails Performance Workshop", timing: false, color: :red) do
|
20
|
-
say "You have completed #{data[:completed]} out of #{data[:total]} total sections."
|
21
|
-
say ""
|
22
|
-
say "Current lesson: #{data[:current_lesson]["title"]}" if data[:current_lesson]
|
23
|
-
say ""
|
24
|
-
::CLI::UI::Frame.open("Progress", timing: false, color: :red) do
|
25
|
-
puts ::CLI::UI.fmt "{{i}} (X == completed, O == current)"
|
26
|
-
say ""
|
27
|
-
data[:sections].each do |section|
|
28
|
-
say "#{section[:title]}: #{section[:progress]}"
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
private
|
35
|
-
|
36
|
-
default_task :show
|
37
|
-
end
|
38
|
-
end
|