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.
@@ -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
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
@@ -0,0 +1,6 @@
1
+ ---
2
+ language: ruby
3
+ cache: bundler
4
+ rvm:
5
+ - 2.7.1
6
+ before_install: gem install bundler -v 2.1.4
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in claw.gemspec
4
+ gemspec
5
+
6
+ gem "rake", "~> 12.0"
7
+ gem "rspec", "~> 3.0"
@@ -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
@@ -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.
@@ -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).
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -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__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -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
@@ -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
@@ -0,0 +1,6 @@
1
+ require 'claw/version'
2
+ require 'claw/autograder'
3
+
4
+ module Claw
5
+ class Error < StandardError; end
6
+ end
@@ -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
@@ -0,0 +1,3 @@
1
+ module Claw
2
+ VERSION = "0.1.0"
3
+ end
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: []