rpw 0.0.6 → 1.0.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 +1 -1
- data/Gemfile.lock +1 -1
- data/HISTORY.md +4 -0
- data/lib/rpw/README.md +43 -7
- data/lib/rpw/cli.rb +2 -4
- data/lib/rpw/cli/key.rb +1 -1
- data/lib/rpw/cli/lesson.rb +12 -10
- data/lib/rpw/cli/progress.rb +6 -4
- data/lib/rpw/client.rb +38 -32
- data/lib/rpw/gateway.rb +6 -2
- data/lib/rpw/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 45b744148f7441c89e4b754ec0b19105e0bfbdb8e9b97e0196d0d6c0ff51266c
|
4
|
+
data.tar.gz: 8eac7fc7584553d6af5e2c250520ff05844e9243882baceeb133f163cee2901e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e20a592d2777d2fbd325cae566fe4e49ed9d07eb496c6da31d1dd70010d08baf08827095c4ffec842e7a9cfeb886d755afd632bedf6e9b671fd3d32fd062382e
|
7
|
+
data.tar.gz: 0b8360255ef4fd5fba85bf982236e44b0f07050a9d45c1f557e047b82d5dd91a243f2c4be96c8202953a3e993c09ecfaec4de9f803c803f038456e952d18cc08
|
data/.github/workflows/test.yml
CHANGED
data/Gemfile.lock
CHANGED
data/HISTORY.md
CHANGED
data/lib/rpw/README.md
CHANGED
@@ -1,22 +1,58 @@
|
|
1
1
|
## Installation Requirements
|
2
2
|
|
3
|
-
This client assumes you
|
3
|
+
This client assumes you're using Ruby 2.3 or later.
|
4
|
+
|
5
|
+
This client assumes you have `tar` installed and available on your PATH.
|
6
|
+
|
7
|
+
The way that the client opens files (using `open` or `xdg-open` depending on platform) assumes you have your default program for the following filetypes set correctly:
|
8
|
+
|
9
|
+
* .md for Markdown (XCode by default on Mac: you probably want to change that!)
|
10
|
+
* .mp4 for videos
|
11
|
+
|
12
|
+
## Slack Invite
|
13
|
+
|
14
|
+
If you purchased the Workshop yourself, you will receive a Slack channel invitation
|
15
|
+
shortly. If you are attending the Workshop as part of a group and your license key
|
16
|
+
was provided to you, you need to register your key to get an invite:
|
17
|
+
|
18
|
+
```
|
19
|
+
$ rpw key register [YOUR_EMAIL_ADDRESS]
|
20
|
+
```
|
21
|
+
|
22
|
+
Please note you can only register your key once.
|
23
|
+
|
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.
|
4
28
|
|
5
29
|
## Important Commands
|
6
30
|
|
7
31
|
Here are some important commands for you to know:
|
8
32
|
|
33
|
+
```
|
9
34
|
$ rpw lesson next | Proceed to the next part of the workshop.
|
10
35
|
$ rpw lesson complete | Mark current lesson as complete.
|
11
36
|
$ rpw lesson list | List all workshop lessons. Note each lesson is preceded with an ID.
|
12
|
-
$ rpw lesson download | Download any or all lessons.
|
13
|
-
$ rpw lesson show | Show any particular workshop lesson.
|
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".
|
14
39
|
$ rpw progress | Show where you're currently at in the workshop.
|
15
|
-
|
40
|
+
```
|
41
|
+
|
42
|
+
Generally, you'll just be doing a lot of `$ rpw lesson next`!
|
16
43
|
|
17
|
-
|
44
|
+
By default, `$ rpw lesson next` will try to open the content it downloads. If you
|
45
|
+
either don't like this, or for some reason it doesn't work, use `$ rpw lesson next --no-open`.
|
18
46
|
|
19
|
-
##
|
47
|
+
## Working Offline
|
48
|
+
|
49
|
+
By default, the course will download each piece of content as you progress through
|
50
|
+
the course. However, you can use `rpw lesson download all` to download all content
|
51
|
+
at once, and complete the workshop entirely offline.
|
20
52
|
|
21
53
|
Videos in this workshop are generally about 100MB each, which means the entire
|
22
|
-
course is about a 3 to 4GB download.
|
54
|
+
course is about a 3 to 4GB download.
|
55
|
+
|
56
|
+
## Bugs and Support
|
57
|
+
|
58
|
+
If you encounter any problems, please email support@speedshop.co for the fastest possible response.
|
data/lib/rpw/cli.rb
CHANGED
@@ -55,9 +55,8 @@ module RPW
|
|
55
55
|
puts ""
|
56
56
|
say "Setup complete!"
|
57
57
|
puts ""
|
58
|
-
say "To learn how to use this command-line client, consult README.md."
|
59
|
-
say "
|
60
|
-
say "Once you're ready to get going: $ rpw lesson next"
|
58
|
+
say "To learn how to use this command-line client, consult ./README.md, which we just created."
|
59
|
+
say "Once you've read that and you're ready to get going: $ rpw lesson next"
|
61
60
|
end
|
62
61
|
|
63
62
|
no_commands do
|
@@ -82,7 +81,6 @@ module RPW
|
|
82
81
|
unless client.latest_version?
|
83
82
|
say "WARNING: You are running an old version of rpw."
|
84
83
|
say "WARNING: Please run `$ gem install rpw`"
|
85
|
-
exit(0)
|
86
84
|
end
|
87
85
|
end
|
88
86
|
|
data/lib/rpw/cli/key.rb
CHANGED
@@ -8,7 +8,7 @@ module RPW
|
|
8
8
|
say "Key registered with #{email}. You should receive a Slack invite soon."
|
9
9
|
else
|
10
10
|
say "Key has already been registered. If you believe this is in error,"\
|
11
|
-
" please email
|
11
|
+
" please email support@speedshop.co"
|
12
12
|
end
|
13
13
|
end
|
14
14
|
end
|
data/lib/rpw/cli/lesson.rb
CHANGED
@@ -3,7 +3,7 @@ module RPW
|
|
3
3
|
class_before :exit_with_no_key
|
4
4
|
|
5
5
|
desc "next", "Proceed to the next lesson of the workshop"
|
6
|
-
option :open
|
6
|
+
option :"no-open"
|
7
7
|
def next
|
8
8
|
say "Proceeding to next lesson..."
|
9
9
|
content = client.next
|
@@ -16,21 +16,23 @@ module RPW
|
|
16
16
|
end
|
17
17
|
|
18
18
|
client.download_and_extract(content)
|
19
|
-
client.
|
20
|
-
display_content(content, options[:open])
|
19
|
+
client.complete(content["position"])
|
20
|
+
display_content(content, !options[:"no-open"])
|
21
21
|
end
|
22
22
|
|
23
23
|
desc "complete", "Mark the current lesson as complete"
|
24
24
|
def complete
|
25
25
|
say "Marked current lesson as complete"
|
26
|
-
client.complete
|
26
|
+
client.complete(nil)
|
27
27
|
end
|
28
28
|
|
29
29
|
desc "list", "Show all available workshop lessons"
|
30
30
|
def list
|
31
31
|
say "All available workshop lessons:"
|
32
|
+
say "Use [ID] for the show/download command"
|
33
|
+
say "[ID]: Lesson Name"
|
32
34
|
client.list.each do |lesson|
|
33
|
-
puts "#{" " * lesson["indent"]}
|
35
|
+
puts "[#{lesson["position"]}]:#{" " * lesson["indent"]} #{lesson["title"]}"
|
34
36
|
end
|
35
37
|
end
|
36
38
|
|
@@ -45,11 +47,11 @@ module RPW
|
|
45
47
|
end
|
46
48
|
|
47
49
|
desc "show [CONTENT]", "Show any workshop lesson, shows current lesson w/no arguments"
|
48
|
-
option :open
|
50
|
+
option :"no-open"
|
49
51
|
def show(content_order = :current)
|
50
52
|
content = client.show(content_order)
|
51
53
|
client.download_and_extract(content)
|
52
|
-
display_content(content, options[:open])
|
54
|
+
display_content(content, !options[:"no-open"])
|
53
55
|
end
|
54
56
|
|
55
57
|
private
|
@@ -65,17 +67,17 @@ module RPW
|
|
65
67
|
Quiz.start(["give_quiz", "quiz/" + content["s3_key"]])
|
66
68
|
when "lab"
|
67
69
|
location = "lab/#{content["s3_key"][0..-8]}"
|
70
|
+
openable = true
|
68
71
|
when "text"
|
69
|
-
location = "
|
72
|
+
location = "text/#{content["s3_key"]}"
|
70
73
|
openable = true
|
71
74
|
when "cgrp"
|
72
75
|
say "The Complete Guide to Rails Performance has been downloaded and extracted to the ./cgrp directory."
|
73
76
|
say "All source code for the CGRP is in the src directory, PDF and other compiled formats are in the release directory."
|
77
|
+
say "You can check it out now, or to continue: $ rpw lesson next "
|
74
78
|
end
|
75
79
|
if location
|
76
80
|
if openable && !open_after
|
77
|
-
say "This file can be opened automatically if you use the --open flag next time."
|
78
|
-
say "e.g. $ rpw lesson next --open"
|
79
81
|
say "Download complete. Open with: $ #{open_command} #{location}"
|
80
82
|
elsif open_after && openable
|
81
83
|
exec "#{open_command} #{location}"
|
data/lib/rpw/cli/progress.rb
CHANGED
@@ -3,14 +3,16 @@ module RPW
|
|
3
3
|
class_before :exit_with_no_key
|
4
4
|
|
5
5
|
desc "set [LESSON]", "Set current lesson to a particular lesson"
|
6
|
-
def set(
|
7
|
-
client.set_progress(
|
6
|
+
def set(pos)
|
7
|
+
lesson = client.set_progress(pos.to_i)
|
8
|
+
say "Set current progress to #{lesson["title"]}"
|
8
9
|
end
|
9
10
|
|
10
11
|
desc "reset", "Erase all progress and start over"
|
11
12
|
def reset
|
12
|
-
yes? "Are you sure you want to reset your progress? (Y/N)"
|
13
|
-
|
13
|
+
return unless yes? "Are you sure you want to reset your progress? (Y/N)"
|
14
|
+
say "Resetting progress."
|
15
|
+
client.set_progress(nil)
|
14
16
|
end
|
15
17
|
|
16
18
|
desc "show", "Show current workshop progress"
|
data/lib/rpw/client.rb
CHANGED
@@ -21,18 +21,30 @@ module RPW
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def next
|
24
|
-
|
25
|
-
|
26
|
-
contents.delete_if { |c| client_data["completed"].include? c["position"] }
|
27
|
-
contents.sort_by { |c| c["position"] }[1] # 0 would be the current lesson
|
24
|
+
return list.first unless client_data["completed"]
|
25
|
+
list.sort_by { |c| c["position"] }.find { |c| c["position"] > current_position }
|
28
26
|
end
|
29
27
|
|
30
28
|
def list
|
31
|
-
|
29
|
+
@list ||= begin
|
30
|
+
if client_data["content_cache_generated"] &&
|
31
|
+
client_data["content_cache_generated"] >= Time.now - 60 * 60
|
32
|
+
|
33
|
+
client_data["content_cache"]
|
34
|
+
else
|
35
|
+
begin
|
36
|
+
client_data["content_cache"] = gateway.list_content
|
37
|
+
client_data["content_cache_generated"] = Time.now
|
38
|
+
client_data["content_cache"]
|
39
|
+
rescue
|
40
|
+
client_data["content_cache"] || (raise Error.new("No internet connection"))
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
32
44
|
end
|
33
45
|
|
34
46
|
def show(content_pos)
|
35
|
-
content_pos =
|
47
|
+
content_pos = current_position if content_pos == :current
|
36
48
|
gateway.get_content_by_position(content_pos)
|
37
49
|
end
|
38
50
|
|
@@ -64,38 +76,28 @@ module RPW
|
|
64
76
|
end
|
65
77
|
end
|
66
78
|
|
67
|
-
def increment_current_lesson!(position)
|
68
|
-
mark_current_lesson_as_completed
|
69
|
-
client_data["current_lesson"] = position
|
70
|
-
end
|
71
|
-
|
72
79
|
def progress
|
73
|
-
contents = gateway.list_content
|
74
80
|
completed_lessons = client_data["completed"] || []
|
75
81
|
{
|
76
82
|
completed: completed_lessons.size,
|
77
|
-
total:
|
78
|
-
current_lesson:
|
79
|
-
sections: chart_section_progress(
|
83
|
+
total: list.size,
|
84
|
+
current_lesson: list.find { |c| c["position"] == current_position },
|
85
|
+
sections: chart_section_progress(list, completed_lessons)
|
80
86
|
}
|
81
87
|
end
|
82
88
|
|
83
|
-
def set_progress(
|
84
|
-
client_data["
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
client_data["completed"] = []
|
89
|
+
def set_progress(pos)
|
90
|
+
client_data["completed"] = [] && return if pos.nil?
|
91
|
+
lesson = list.find { |l| l["position"] == pos }
|
92
|
+
raise Error.new("No such lesson - use the IDs in $ rpw lesson list") unless lesson
|
93
|
+
client_data["completed"] += [pos]
|
94
|
+
lesson
|
90
95
|
end
|
91
96
|
|
92
97
|
def latest_version?
|
93
98
|
return true unless ClientData.exists?
|
94
|
-
|
95
|
-
|
96
|
-
return true if client_data["last_version_check"] >= Time.now - (60 * 60 * 24)
|
97
|
-
return false if client_data["last_version_check"] == false
|
98
|
-
end
|
99
|
+
return true if client_data["last_version_check"] &&
|
100
|
+
client_data["last_version_check"] >= Time.now - (60 * 60)
|
99
101
|
|
100
102
|
begin
|
101
103
|
latest = gateway.latest_version?
|
@@ -129,19 +131,23 @@ module RPW
|
|
129
131
|
end
|
130
132
|
end
|
131
133
|
|
134
|
+
def complete(position)
|
135
|
+
reset_progress unless client_data["completed"]
|
136
|
+
# we actually have to put the _next_ lesson on the completed stack
|
137
|
+
set_progress(self.next["position"])
|
138
|
+
end
|
139
|
+
|
132
140
|
private
|
133
141
|
|
134
|
-
def
|
135
|
-
|
136
|
-
client_data["completed"] ||= []
|
137
|
-
client_data["completed"] += [client_data["current_lesson"] || 0]
|
142
|
+
def current_position
|
143
|
+
@current_position ||= client_data["completed"]&.last || 0
|
138
144
|
end
|
139
145
|
|
140
146
|
def chart_section_progress(contents, completed)
|
141
147
|
contents.group_by { |c| c["position"] / 100 }
|
142
148
|
.each_with_object([]) do |(_, c), memo|
|
143
149
|
completed_str = c.map { |l|
|
144
|
-
if l["position"] ==
|
150
|
+
if l["position"] == current_position
|
145
151
|
"O"
|
146
152
|
elsif completed.include?(l["position"])
|
147
153
|
"X"
|
data/lib/rpw/gateway.rb
CHANGED
@@ -42,9 +42,13 @@ module RPW
|
|
42
42
|
streamer = lambda do |chunk, remaining_bytes, total_bytes|
|
43
43
|
downloaded_file.write(chunk)
|
44
44
|
print 13.chr
|
45
|
-
print "Remaining: #{(remaining_bytes.to_f / total_bytes * 100).round(2).to_s.rjust(8)}%"
|
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}")
|
46
51
|
end
|
47
|
-
Excon.get(content["url"], response_block: streamer)
|
48
52
|
downloaded_file.close
|
49
53
|
print "\n"
|
50
54
|
File.rename(downloaded_file, "#{folder}/#{content["s3_key"]}")
|
data/lib/rpw/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rpw
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nate Berkopec
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-11-
|
11
|
+
date: 2020-11-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|