rpw 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aee4cd056139ea78d75fc48a6c0337c32c7e9ca958ac0c24716ec7a27abc5617
4
- data.tar.gz: 6688f3f8b1edef9c6004af6146d10e4d6b190d103f95ee233902523f73760043
3
+ metadata.gz: 317f37137765f78e5a587b36e3ecb4898d18e4b011cc3ef67f60d5d0e710c6d8
4
+ data.tar.gz: 4c9f5e3edf56c6dad2d887e4653d358850255dbf9682e0a6fcc8261e0e3a543f
5
5
  SHA512:
6
- metadata.gz: 5682fb0676abd4d9a69ecee1193a332ed7d580ea5d8f37919d2925da01d64a4f911cb042ec0ec8e72e39479f75f3cb3fdfac3d640a178dd3d70f3b7c41bdf396
7
- data.tar.gz: edc9f5b0994db202b3b9b94838efeec9ecc26f7d52e05e8fc73c35a6c22e10ff969e9065cb66a51c2151c31c93fea9e07f6a6277c420fbd6832ba58fe510f69d
6
+ metadata.gz: 7526987cc970e87b387154632256c89190b8cb7ec9fb9cfe9f1fe2364e73a46cabe81ecbe6a6707e8d5c7ca2c3a5f1591f2bf27d8b63a4e801ff69fcfefa1f11
7
+ data.tar.gz: eeb1628660e72e1d655e428c0640b6255ba43794db4704b42293eee6975a7f1a157c345ba6f2e87e8952af4198750d7aa271f7c925c4977d8f50e0f3e8fdb837
@@ -1,7 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rpw (1.0.1)
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
@@ -1,3 +1,7 @@
1
+ ## 1.1.0
2
+
3
+ * sick colors
4
+
1
5
  ## 1.0.1
2
6
 
3
7
  * Pre-launch bugfix
@@ -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 any or all lessons. Use the IDs from "list".
38
- $ rpw lesson show | Show any particular workshop lesson. Use the IDs from "list".
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
 
@@ -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
- key = ask("Your Purchase Key: ")
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 yes? "You have already started the workshop. Continuing "\
77
- "this command will wipe all of your current progress. Continue? (y/N)"
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
@@ -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
- say "All available workshop lessons:"
32
- say "Use [ID] for the show/download command"
33
- say "[ID]: Lesson Name"
30
+ ::CLI::UI::Frame.open("{{*}} {{bold:All Lessons}}", color: :green)
31
+
32
+ frame_open = false
34
33
  client.list.each do |lesson|
35
- puts "[#{lesson["position"]}]:#{" " * lesson["indent"]} #{lesson["title"]}"
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 [CONTENT | all]", "Download one or all workshop contents"
40
- def download(content_pos)
41
- to_download = if content_pos.downcase == "all"
42
- client.list
43
- else
44
- [client.show(content_pos)]
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 [CONTENT]", "Show any workshop lesson, shows current lesson w/no arguments"
70
+ desc "show", "Show any individal workshop lesson"
50
71
  option :"no-open"
51
- def show(content_order = :current)
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"])
@@ -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 yes? "Are you sure you want to reset your progress? (Y/N)"
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
- say "The Rails Performance Workshop"
22
- say "You have completed #{data[:completed]} out of #{data[:total]} total sections."
23
- say "Current lesson: #{data[:current_lesson]["title"]}" if data[:current_lesson]
24
- say "Progress by Section (X == completed, O == current):"
25
- data[:sections].each do |section|
26
- say "#{section[:title]}: #{section[: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
27
31
  end
28
32
  end
29
33
 
@@ -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.upcase)
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
@@ -44,8 +44,7 @@ module RPW
44
44
  end
45
45
 
46
46
  def show(content_pos)
47
- content_pos = current_position if content_pos == :current
48
- gateway.get_content_by_position(content_pos)
47
+ list.find { |l| l["position"] == content_pos }
49
48
  end
50
49
 
51
50
  def directory_setup(home_dir_ok = true)
@@ -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
- Check your file permissions."
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
 
@@ -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
- puts "Downloading #{content["title"]}..."
41
- downloaded_file = File.open("#{folder}/#{content["s3_key"]}.partial", "w")
42
- streamer = lambda do |chunk, remaining_bytes, total_bytes|
43
- downloaded_file.write(chunk)
44
- print 13.chr
45
- print "Remaining: #{(remaining_bytes.to_f / total_bytes * 100).round(2).to_s.rjust(8)}%" if remaining_bytes
46
- end
47
- response = Excon.get(content["url"], response_block: streamer)
48
- unless response.status == 200
49
- puts response.inspect
50
- raise Error.new("Server problem: #{response.status}")
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?
@@ -1,3 +1,3 @@
1
1
  module RPW
2
- VERSION = "1.0.1"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -27,4 +27,5 @@ Gem::Specification.new do |spec|
27
27
  spec.add_dependency "thor"
28
28
  spec.add_dependency "thor-hollaback"
29
29
  spec.add_dependency "excon"
30
+ spec.add_dependency "cli-ui"
30
31
  end
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.1
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