rpw 1.0.1 → 1.1.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/Gemfile.lock +3 -1
- data/HISTORY.md +4 -0
- data/lib/rpw/README.md +2 -2
- data/lib/rpw/cli.rb +21 -18
- data/lib/rpw/cli/lesson.rb +43 -15
- data/lib/rpw/cli/progress.rb +13 -9
- data/lib/rpw/cli/quiz.rb +2 -2
- data/lib/rpw/client.rb +1 -2
- data/lib/rpw/client_data.rb +2 -2
- data/lib/rpw/gateway.rb +14 -24
- data/lib/rpw/version.rb +1 -1
- data/rpw.gemspec +1 -0
- metadata +15 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 317f37137765f78e5a587b36e3ecb4898d18e4b011cc3ef67f60d5d0e710c6d8
|
4
|
+
data.tar.gz: 4c9f5e3edf56c6dad2d887e4653d358850255dbf9682e0a6fcc8261e0e3a543f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7526987cc970e87b387154632256c89190b8cb7ec9fb9cfe9f1fe2364e73a46cabe81ecbe6a6707e8d5c7ca2c3a5f1591f2bf27d8b63a4e801ff69fcfefa1f11
|
7
|
+
data.tar.gz: eeb1628660e72e1d655e428c0640b6255ba43794db4704b42293eee6975a7f1a157c345ba6f2e87e8952af4198750d7aa271f7c925c4977d8f50e0f3e8fdb837
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rpw (1.0
|
4
|
+
rpw (1.1.0)
|
5
|
+
cli-ui
|
5
6
|
excon
|
6
7
|
thor
|
7
8
|
thor-hollaback
|
@@ -10,6 +11,7 @@ GEM
|
|
10
11
|
remote: https://rubygems.org/
|
11
12
|
specs:
|
12
13
|
ast (2.4.1)
|
14
|
+
cli-ui (1.4.0)
|
13
15
|
excon (0.78.0)
|
14
16
|
hollaback (0.1.0)
|
15
17
|
minitest (5.14.2)
|
data/HISTORY.md
CHANGED
data/lib/rpw/README.md
CHANGED
@@ -34,8 +34,8 @@ Here are some important commands for you to know:
|
|
34
34
|
$ rpw lesson next | Proceed to the next part of the workshop.
|
35
35
|
$ rpw lesson complete | Mark current lesson as complete.
|
36
36
|
$ rpw lesson list | List all workshop lessons. Note each lesson is preceded with an ID.
|
37
|
-
$ rpw lesson download | Download
|
38
|
-
$ rpw lesson show | Show any particular workshop lesson.
|
37
|
+
$ rpw lesson download | Download all lessons. Useful for offline access.
|
38
|
+
$ rpw lesson show | Show any particular workshop lesson.
|
39
39
|
$ rpw progress | Show where you're currently at in the workshop.
|
40
40
|
```
|
41
41
|
|
data/lib/rpw/cli.rb
CHANGED
@@ -6,11 +6,13 @@ require "rpw/cli/sub_command_base"
|
|
6
6
|
require "rpw/cli/key"
|
7
7
|
require "rpw/cli/lesson"
|
8
8
|
require "rpw/cli/progress"
|
9
|
+
require "cli/ui"
|
10
|
+
|
11
|
+
CLI::UI::StdoutRouter.enable
|
9
12
|
|
10
13
|
module RPW
|
11
14
|
class CLI < Thor
|
12
15
|
class_before :check_version
|
13
|
-
class_before :check_setup
|
14
16
|
|
15
17
|
desc "key register [EMAIL_ADDRESS]", "Change email registered w/Speedshop"
|
16
18
|
subcommand "key", Key
|
@@ -28,7 +30,7 @@ module RPW
|
|
28
30
|
warn_if_already_started
|
29
31
|
|
30
32
|
print_banner
|
31
|
-
say "Welcome to the Rails Performance Workshop."
|
33
|
+
say "\u{1F48E} Welcome to the Rails Performance Workshop. \u{1F48E}"
|
32
34
|
say ""
|
33
35
|
say "This is rpw, the command line client for this workshop."
|
34
36
|
say ""
|
@@ -36,14 +38,22 @@ module RPW
|
|
36
38
|
say "working directory, so it's best to run this client from a new directory"
|
37
39
|
say "that you'll use as your 'scratch space' for working on the Workshop."
|
38
40
|
say ""
|
39
|
-
say "We will create a handful of new files and folders in the current directory."
|
40
|
-
return unless yes? "Is this OK? (y/N) (N will quit)"
|
41
|
-
puts ""
|
42
|
-
say "We'll also create a .rpw_info file at #{File.expand_path("~/.rpw")} to save your purchase key."
|
43
|
-
home_dir_ok = yes?("Is this OK? (y/N) (N will create it in the current directory)")
|
44
|
-
client.directory_setup(home_dir_ok)
|
45
41
|
|
46
|
-
|
42
|
+
ans = ::CLI::UI.confirm "Create files and folders in this directory? (no will quit)"
|
43
|
+
|
44
|
+
exit(1) unless ans
|
45
|
+
|
46
|
+
say ""
|
47
|
+
|
48
|
+
ans = ::CLI::UI::Prompt.ask("Where should we save your course progress?",
|
49
|
+
options: [
|
50
|
+
"here",
|
51
|
+
"my home directory (~/.rpw)"
|
52
|
+
])
|
53
|
+
|
54
|
+
client.directory_setup((ans == "my home directory (~/.rpw)"))
|
55
|
+
|
56
|
+
key = ::CLI::UI::Prompt.ask("Your Purchase Key: ")
|
47
57
|
|
48
58
|
unless client.setup(key)
|
49
59
|
say "That is not a valid key. Please try again."
|
@@ -73,8 +83,8 @@ module RPW
|
|
73
83
|
|
74
84
|
def warn_if_already_started
|
75
85
|
return unless client.setup?
|
76
|
-
exit(0) unless
|
77
|
-
"this command will wipe all of your current progress. Continue?
|
86
|
+
exit(0) unless ::CLI::UI.confirm "You have already started the workshop. Continuing "\
|
87
|
+
"this command will wipe all of your current progress. Continue?", default: false
|
78
88
|
end
|
79
89
|
|
80
90
|
def check_version
|
@@ -83,12 +93,5 @@ module RPW
|
|
83
93
|
say "WARNING: Please run `$ gem install rpw`"
|
84
94
|
end
|
85
95
|
end
|
86
|
-
|
87
|
-
def check_setup
|
88
|
-
unless client.setup? || current_command_chain == [:start]
|
89
|
-
say "WARNING: You do not have a purchase key set. Run `$ rpw start`"
|
90
|
-
exit(0)
|
91
|
-
end
|
92
|
-
end
|
93
96
|
end
|
94
97
|
end
|
data/lib/rpw/cli/lesson.rb
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
module RPW
|
2
2
|
class Lesson < SubCommandBase
|
3
|
-
class_before :exit_with_no_key
|
4
|
-
|
5
3
|
desc "next", "Proceed to the next lesson of the workshop"
|
6
4
|
option :"no-open"
|
7
5
|
def next
|
6
|
+
exit_with_no_key
|
8
7
|
say "Proceeding to next lesson..."
|
9
8
|
content = client.next
|
10
9
|
|
@@ -28,27 +27,56 @@ module RPW
|
|
28
27
|
|
29
28
|
desc "list", "Show all available workshop lessons"
|
30
29
|
def list
|
31
|
-
|
32
|
-
|
33
|
-
|
30
|
+
::CLI::UI::Frame.open("{{*}} {{bold:All Lessons}}", color: :green)
|
31
|
+
|
32
|
+
frame_open = false
|
34
33
|
client.list.each do |lesson|
|
35
|
-
|
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
|
36
53
|
end
|
54
|
+
|
55
|
+
::CLI::UI::Frame.close(nil)
|
56
|
+
::CLI::UI::Frame.close(nil, color: :green)
|
37
57
|
end
|
38
58
|
|
39
|
-
desc "download
|
40
|
-
def download
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
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)
|
45
67
|
end
|
46
|
-
to_download.each { |content| client.download_and_extract(content) }
|
47
68
|
end
|
48
69
|
|
49
|
-
desc "show
|
70
|
+
desc "show", "Show any individal workshop lesson"
|
50
71
|
option :"no-open"
|
51
|
-
def show
|
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"]
|
52
80
|
content = client.show(content_order)
|
53
81
|
client.download_and_extract(content)
|
54
82
|
display_content(content, !options[:"no-open"])
|
data/lib/rpw/cli/progress.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
module RPW
|
2
2
|
class Progress < SubCommandBase
|
3
|
-
class_before :exit_with_no_key
|
4
|
-
|
5
3
|
desc "set [LESSON]", "Set current lesson to a particular lesson"
|
6
4
|
def set(pos)
|
7
5
|
lesson = client.set_progress(pos.to_i)
|
@@ -10,7 +8,7 @@ module RPW
|
|
10
8
|
|
11
9
|
desc "reset", "Erase all progress and start over"
|
12
10
|
def reset
|
13
|
-
return unless
|
11
|
+
return unless ::CLI::UI.confirm("Are you sure you want to erase all of your progress?", default: false)
|
14
12
|
say "Resetting progress."
|
15
13
|
client.set_progress(nil)
|
16
14
|
end
|
@@ -18,12 +16,18 @@ module RPW
|
|
18
16
|
desc "show", "Show current workshop progress"
|
19
17
|
def show
|
20
18
|
data = client.progress
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
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
|
27
31
|
end
|
28
32
|
end
|
29
33
|
|
data/lib/rpw/cli/quiz.rb
CHANGED
@@ -14,8 +14,8 @@ module RPW
|
|
14
14
|
def question(data)
|
15
15
|
puts data["prompt"]
|
16
16
|
data["answer_choices"].each { |ac| puts ac }
|
17
|
-
provided_answer = ask("Your answer?")
|
18
|
-
answer_digest = Digest::MD5.hexdigest(data["prompt"] + provided_answer
|
17
|
+
provided_answer = ::CLI::UI::Prompt.ask("Your answer?", options: %w[A B C D])
|
18
|
+
answer_digest = Digest::MD5.hexdigest(data["prompt"] + provided_answer)
|
19
19
|
if answer_digest == data["answer_digest"]
|
20
20
|
say "Correct!"
|
21
21
|
else
|
data/lib/rpw/client.rb
CHANGED
data/lib/rpw/client_data.rb
CHANGED
@@ -20,8 +20,8 @@ module RPW
|
|
20
20
|
begin
|
21
21
|
File.open(filestore_location, "w") { |f| f.write(YAML.dump(data)) }
|
22
22
|
rescue
|
23
|
-
raise Error, "The RPW data at #{filestore_location} is not writable. \
|
24
|
-
|
23
|
+
# raise Error, "The RPW data at #{filestore_location} is not writable. \
|
24
|
+
# Check your file permissions."
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
data/lib/rpw/gateway.rb
CHANGED
@@ -16,16 +16,6 @@ module RPW
|
|
16
16
|
Excon.get(domain + "/license", user: key).status == 200
|
17
17
|
end
|
18
18
|
|
19
|
-
def get_content_by_position(position)
|
20
|
-
response = Excon.get(domain + "/contents/positional?position=#{position}", user: @key)
|
21
|
-
if response.status == 200
|
22
|
-
JSON.parse(response.body)
|
23
|
-
else
|
24
|
-
puts response.inspect
|
25
|
-
raise Error, "There was a problem fetching this content."
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
19
|
def list_content
|
30
20
|
response = Excon.get(domain + "/contents", user: @key)
|
31
21
|
if response.status == 200
|
@@ -37,21 +27,21 @@ module RPW
|
|
37
27
|
end
|
38
28
|
|
39
29
|
def download_content(content, folder:)
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
30
|
+
::CLI::UI::Progress.progress do |bar|
|
31
|
+
downloaded_file = File.open("#{folder}/#{content["s3_key"]}.partial", "w")
|
32
|
+
streamer = lambda do |chunk, remaining_bytes, total_bytes|
|
33
|
+
downloaded_file.write(chunk)
|
34
|
+
bar.tick(set_percent: 1 - (remaining_bytes.to_f / total_bytes).round(2))
|
35
|
+
end
|
36
|
+
response = Excon.get(content["url"], response_block: streamer)
|
37
|
+
unless response.status == 200
|
38
|
+
puts response.inspect
|
39
|
+
raise Error.new("Server problem: #{response.status}")
|
40
|
+
end
|
41
|
+
downloaded_file.close
|
42
|
+
File.rename(downloaded_file, "#{folder}/#{content["s3_key"]}")
|
43
|
+
bar.tick(set_percent: 1)
|
51
44
|
end
|
52
|
-
downloaded_file.close
|
53
|
-
print "\n"
|
54
|
-
File.rename(downloaded_file, "#{folder}/#{content["s3_key"]}")
|
55
45
|
end
|
56
46
|
|
57
47
|
def latest_version?
|
data/lib/rpw/version.rb
CHANGED
data/rpw.gemspec
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.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nate Berkopec
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: cli-ui
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
description:
|
56
70
|
email:
|
57
71
|
- nate@speedshop.co
|