rpw 0.0.6 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|