claw 0.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 +7 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.travis.yml +6 -0
- data/Gemfile +7 -0
- data/Gemfile.lock +44 -0
- data/LICENSE.txt +21 -0
- data/README.md +66 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/claw.gemspec +28 -0
- data/exe/claw +72 -0
- data/lib/claw.rb +6 -0
- data/lib/claw/autograder.rb +64 -0
- data/lib/claw/version.rb +3 -0
- metadata +89 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a01d7797a095f7f3e01bc18ea036b5cabf7ba5740faa8d2314829c1eebf93554
|
4
|
+
data.tar.gz: 7f69f0503747146d07cdf3de5b4e0db7e9504374bb21d7cb51936ee4cd8ea77e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: cf936c9d8dc51000a74ffe42ac530363a44f9d77e1422e46ef101611a4d796c681c6d04b64f6beb415344c433eec70a35c73ebd8a5b6af45bc8bd690ba71f17d
|
7
|
+
data.tar.gz: 3d4230a9e246a26357fc746a322cb898aea194996fd47ed9d18c9e4785fbae4eaf2a951353c569d1f961bf2fbb8fc90a27bfb048e88249ecca2ba366d5afeb45
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
claw (0.1.0)
|
5
|
+
highlight
|
6
|
+
httparty
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
diff-lcs (1.4.4)
|
12
|
+
highlight (2.0.0)
|
13
|
+
httparty (0.18.1)
|
14
|
+
mime-types (~> 3.0)
|
15
|
+
multi_xml (>= 0.5.2)
|
16
|
+
mime-types (3.3.1)
|
17
|
+
mime-types-data (~> 3.2015)
|
18
|
+
mime-types-data (3.2020.0512)
|
19
|
+
multi_xml (0.6.0)
|
20
|
+
rake (12.3.3)
|
21
|
+
rspec (3.9.0)
|
22
|
+
rspec-core (~> 3.9.0)
|
23
|
+
rspec-expectations (~> 3.9.0)
|
24
|
+
rspec-mocks (~> 3.9.0)
|
25
|
+
rspec-core (3.9.3)
|
26
|
+
rspec-support (~> 3.9.3)
|
27
|
+
rspec-expectations (3.9.2)
|
28
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
29
|
+
rspec-support (~> 3.9.0)
|
30
|
+
rspec-mocks (3.9.1)
|
31
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
32
|
+
rspec-support (~> 3.9.0)
|
33
|
+
rspec-support (3.9.3)
|
34
|
+
|
35
|
+
PLATFORMS
|
36
|
+
ruby
|
37
|
+
|
38
|
+
DEPENDENCIES
|
39
|
+
claw!
|
40
|
+
rake (~> 12.0)
|
41
|
+
rspec (~> 3.0)
|
42
|
+
|
43
|
+
BUNDLED WITH
|
44
|
+
2.1.4
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2020 Neil Johari
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
# Claw
|
2
|
+
|
3
|
+
Welcome to Claw, a CLI for UofM teaching staff to help students more effectively.
|
4
|
+
|
5
|
+
Claw downloads a student's latest [Autograder](https://autograder.io) submission locally and then prompts the instructor to run all AG tests locally along with the option to sync to CAEN.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Run `gem install claw` in your command line.
|
10
|
+
|
11
|
+
## Usage
|
12
|
+
|
13
|
+
### Obtaining a Token
|
14
|
+
|
15
|
+
> Log in to autograder.io in Chrome and open up the developer tools from the Chrome menu (View->Developer->Developer Tools on a Mac).
|
16
|
+
> Click on a course link.
|
17
|
+
> In the developer console, click on a request (e.g. my_roles/ or projects/). Under Request Headers, there is an Authorization entry that looks like "Token ".
|
18
|
+
> Copy the hex string and save it to the file .agtoken in your home directory.
|
19
|
+
> -- <cite>[autograder-contrib](https://github.com/eecs-autograder/autograder-contrib)</cite>
|
20
|
+
|
21
|
+
### Setting Up a Solution Repository
|
22
|
+
|
23
|
+
1. Clone a solution repository (like `eecs280staff/<solution repo>`) locally via `git clone`
|
24
|
+
2. Ensure the solution repo Makefile has an `autograde` target (all EECS280 project repos do)
|
25
|
+
3. Optionally add a `sync` target to the Makefile. This target should sync _the
|
26
|
+
entire_ solution repo to CAEN. An example target would be:
|
27
|
+
|
28
|
+
```
|
29
|
+
# Copy files to CAEN Linux
|
30
|
+
sync :
|
31
|
+
rsync \
|
32
|
+
-rtv \
|
33
|
+
--delete \
|
34
|
+
--exclude '.git*' \
|
35
|
+
--filter=':- .gitignore' \
|
36
|
+
./ \
|
37
|
+
<your uniqname here>@login.engin.umich.edu:ia-280-p3
|
38
|
+
```
|
39
|
+
|
40
|
+
### Running Claw
|
41
|
+
|
42
|
+
In a solution repo, run `claw <project id> <student uniqname>`.
|
43
|
+
|
44
|
+
You can determine the project id by navigating to the project on `autograder.io` and looking at the URL.
|
45
|
+
For instance, in Fall 2020, EECS280's Euchre project was available at [https://autograder.io/web/project/721](https://autograder.io/web/project/721) which means the project id was `721`.
|
46
|
+
|
47
|
+
This will download a json file containing all groups of students who have submitted to the Autograder (including those working alone) and then download the given student's latest solution into a directory `./<uniqname>/`.
|
48
|
+
Subsequent runs will reuse the previously downloaded json file; you should delete this file periodically to keep your list of students up to date.
|
49
|
+
|
50
|
+
Claw will then prompt to run all private autograder tests from the repo. It assumes the Makefile has an `autograde` target, and will dump the output to a file called `autograder.io`.
|
51
|
+
|
52
|
+
Finally, Claw will prompt the user whether to upload to CAEN. It assumes the Makefile has a `sync` target.
|
53
|
+
|
54
|
+
## Development
|
55
|
+
|
56
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
57
|
+
|
58
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
59
|
+
|
60
|
+
## Contributing
|
61
|
+
|
62
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/neiljohari/claw.
|
63
|
+
|
64
|
+
## License
|
65
|
+
|
66
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "claw"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/claw.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require_relative 'lib/claw/version'
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = "claw"
|
5
|
+
spec.version = Claw::VERSION
|
6
|
+
spec.authors = ["Neil Johari"]
|
7
|
+
spec.email = ["neil@johari.tech"]
|
8
|
+
|
9
|
+
spec.summary = %q{A tool for staff to quickly download student AG submissions}
|
10
|
+
spec.homepage = "https://eecs280staff.github.io/eecs280.org/"
|
11
|
+
spec.license = "MIT"
|
12
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
|
13
|
+
|
14
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
15
|
+
spec.metadata["source_code_uri"] = "https://github.com/neiljohari/claw/"
|
16
|
+
|
17
|
+
# Specify which files should be added to the gem when it is released.
|
18
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
19
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
20
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
21
|
+
end
|
22
|
+
spec.bindir = "exe"
|
23
|
+
spec.executables = ['claw']
|
24
|
+
spec.require_paths = ["lib"]
|
25
|
+
|
26
|
+
spec.add_runtime_dependency 'highlight'
|
27
|
+
spec.add_runtime_dependency 'httparty'
|
28
|
+
end
|
data/exe/claw
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'claw'
|
4
|
+
require 'fileutils'
|
5
|
+
require 'English'
|
6
|
+
require 'highline/import'
|
7
|
+
|
8
|
+
def last_submission(submissions)
|
9
|
+
if submissions.empty?
|
10
|
+
warn 'No submissions for user'
|
11
|
+
exit
|
12
|
+
end
|
13
|
+
submissions[0].slice('pk', 'submitted_filenames')
|
14
|
+
end
|
15
|
+
|
16
|
+
if ARGV.length != 2
|
17
|
+
warn 'Usage: claw <project_id> <uniqname>'
|
18
|
+
exit
|
19
|
+
end
|
20
|
+
|
21
|
+
token_file_path = File.join(ENV['HOME'], '.agtoken')
|
22
|
+
unless File.exist? token_file_path
|
23
|
+
warn %{
|
24
|
+
Log in to autograder.io in Chrome and open up the developer tools from the Chrome menu (View->Developer->Developer Tools on a Mac)
|
25
|
+
|
26
|
+
Click on a course link. In the developer console, click on a request (e.g. my_roles/ or projects/).
|
27
|
+
|
28
|
+
Under Request Headers, there is an Authorization entry that looks like "Token".
|
29
|
+
|
30
|
+
Copy the hex string and save it to the file .agtoken in your home directory.
|
31
|
+
}
|
32
|
+
exit
|
33
|
+
end
|
34
|
+
|
35
|
+
token = File.read(token_file_path)
|
36
|
+
ag = Claw::Autograder.new(token)
|
37
|
+
|
38
|
+
groupid = ag.get_group_id_from_uniqname(ARGV[0], "#{ARGV[1]}@umich.edu")
|
39
|
+
unless groupid
|
40
|
+
warn %{
|
41
|
+
Group for student not found! Double check their uniqname.
|
42
|
+
|
43
|
+
It is also possible this person registered their group after Claw cached the groups in the json file.
|
44
|
+
Try deleting the json file and rerunning the command.
|
45
|
+
}
|
46
|
+
exit
|
47
|
+
end
|
48
|
+
|
49
|
+
ag.download_files(ARGV[1], last_submission(ag.submissions(groupid)))
|
50
|
+
|
51
|
+
# Run tests
|
52
|
+
if HighLine.agree('Run tests? [Y/N]')
|
53
|
+
# Update SOL=? in the Makefile
|
54
|
+
mkfile_path = File.join(Dir.pwd, 'Makefile')
|
55
|
+
|
56
|
+
unless File.exist? mkfile_path
|
57
|
+
warn 'Could not find Makefile. You should run this from within a project repo (such as eecs280staff/p3-euchre for example)'
|
58
|
+
exit
|
59
|
+
end
|
60
|
+
|
61
|
+
mklines = File.readlines(mkfile_path)
|
62
|
+
mklines[1] = "SOL ?= #{ARGV[1]}" << $INPUT_RECORD_SEPARATOR
|
63
|
+
File.open(mkfile_path, 'w') { |f| f.write(mklines.join) }
|
64
|
+
|
65
|
+
`make autograde > autograder.txt`
|
66
|
+
puts 'The student autograder output has been dumped to autograder.txt'
|
67
|
+
end
|
68
|
+
|
69
|
+
# Sync to CAEN
|
70
|
+
if HighLine.agree('Upload to CAEN? [Y/N]')
|
71
|
+
`make sync`
|
72
|
+
end
|
data/lib/claw.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'httparty'
|
3
|
+
|
4
|
+
module Claw
|
5
|
+
# Autograder HTTParty Client Wrapper
|
6
|
+
class Autograder
|
7
|
+
include HTTParty
|
8
|
+
base_uri 'autograder.io'
|
9
|
+
|
10
|
+
def initialize(token, query = {})
|
11
|
+
@options = {
|
12
|
+
headers: {
|
13
|
+
'Accept' => 'application/json, text/plain, */*',
|
14
|
+
'Authorization' => "Token #{token}",
|
15
|
+
'Cookie' => "token=#{token}"
|
16
|
+
},
|
17
|
+
query: query,
|
18
|
+
verify: false
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
def download_groups(projectid)
|
23
|
+
puts 'Downloading groups json file (this could take a while)...'
|
24
|
+
File.open(File.join(Dir.pwd, "project_#{projectid}_groups.json"), 'w') do |f|
|
25
|
+
f.write(self.class.get("/api/projects/#{projectid}/groups/", @options))
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def get_group_id_from_uniqname(projectid, name)
|
30
|
+
puts 'Searching for user group id...'
|
31
|
+
download_groups(projectid) unless File.exist? "project_#{projectid}_groups.json"
|
32
|
+
|
33
|
+
groups_json = JSON.parse(File.read(File.join(Dir.pwd, "project_#{projectid}_groups.json")))
|
34
|
+
|
35
|
+
groups_json.each do |group|
|
36
|
+
return group['pk'] if group['member_names'].include?(name)
|
37
|
+
end
|
38
|
+
|
39
|
+
nil
|
40
|
+
end
|
41
|
+
|
42
|
+
def submissions(groupid)
|
43
|
+
puts 'Fetching group submissions...'
|
44
|
+
self.class.get("/api/groups/#{groupid}/submissions/", @options)
|
45
|
+
end
|
46
|
+
|
47
|
+
def download_files(dirname, submission)
|
48
|
+
puts 'Downloading submission files...'
|
49
|
+
FileUtils.mkdir_p(File.join(Dir.pwd, dirname))
|
50
|
+
|
51
|
+
submission['submitted_filenames'].each do |filename|
|
52
|
+
opt_merge = {
|
53
|
+
query: {
|
54
|
+
'filename' => filename
|
55
|
+
}
|
56
|
+
}
|
57
|
+
|
58
|
+
File.open(File.join(Dir.pwd, dirname, filename), 'w') do |f|
|
59
|
+
f.write(self.class.get("/api/submissions/#{submission['pk']}/file/", @options.merge(opt_merge)))
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/lib/claw/version.rb
ADDED
metadata
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: claw
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Neil Johari
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-10-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: highlight
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: httparty
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description:
|
42
|
+
email:
|
43
|
+
- neil@johari.tech
|
44
|
+
executables:
|
45
|
+
- claw
|
46
|
+
extensions: []
|
47
|
+
extra_rdoc_files: []
|
48
|
+
files:
|
49
|
+
- ".gitignore"
|
50
|
+
- ".rspec"
|
51
|
+
- ".travis.yml"
|
52
|
+
- Gemfile
|
53
|
+
- Gemfile.lock
|
54
|
+
- LICENSE.txt
|
55
|
+
- README.md
|
56
|
+
- Rakefile
|
57
|
+
- bin/console
|
58
|
+
- bin/setup
|
59
|
+
- claw.gemspec
|
60
|
+
- exe/claw
|
61
|
+
- lib/claw.rb
|
62
|
+
- lib/claw/autograder.rb
|
63
|
+
- lib/claw/version.rb
|
64
|
+
homepage: https://eecs280staff.github.io/eecs280.org/
|
65
|
+
licenses:
|
66
|
+
- MIT
|
67
|
+
metadata:
|
68
|
+
homepage_uri: https://eecs280staff.github.io/eecs280.org/
|
69
|
+
source_code_uri: https://github.com/neiljohari/claw/
|
70
|
+
post_install_message:
|
71
|
+
rdoc_options: []
|
72
|
+
require_paths:
|
73
|
+
- lib
|
74
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: 2.3.0
|
79
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
requirements: []
|
85
|
+
rubygems_version: 3.1.2
|
86
|
+
signing_key:
|
87
|
+
specification_version: 4
|
88
|
+
summary: A tool for staff to quickly download student AG submissions
|
89
|
+
test_files: []
|