Created
April 20, 2012 01:28
-
-
Save axiixc/2425195 to your computer and use it in GitHub Desktop.
Send assignments to the PLC grading server. Only tested for students.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
echo "Zipping assignment..." | |
zip assignment.zip file1.ss file2.ss file3.ss main.ss >> /dev/null | |
if [ $? -eq 0 ] | |
then | |
plcsend --send-file assignment.zip -user YOUR_USERNAME -pass YOUR_PASSWORD -id ASSIGNMENT_ID | |
else | |
echo "Error creating zip" | |
fi |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/ruby | |
require 'rubygems' | |
require 'net/https' | |
require 'net/http/post/multipart' # sudo gem install multipart-post | |
require 'nokogiri' # sudo gem install nokogiri | |
require 'base64' | |
class PLCServerSession | |
API_BASE = 'https://plc.csse.rose-hulman.edu/' | |
API_NODES = { | |
# user[username] = [string:student_username] | |
# user[password] = [string:student_password] | |
:authenticate => { | |
:path => 'user/login_submit', | |
:method => :post | |
}, | |
# List results of selected assignment | |
# Can also be used to change selected assignment | |
# Optionl: as_id = [int] | |
:assignments => { | |
:path => 'student/assignment', | |
:method => :get | |
}, | |
# Submit an assignment | |
# submission[assignment_id] = [int] | |
# submission[submitted_file] = [file] | |
# submission[users] = [string:usernames] | |
:assignment_submit => { | |
:path => 'student/assignment_submit', | |
:method => :post_multipart | |
} | |
} | |
def send_file(path, id) | |
if !File.exists?(path) | |
puts "File not found: #{path}" | |
exit 1 | |
end | |
puts "Sending assignment..." | |
response = nil | |
File.open(path) do |file| | |
response = make_api_request(:assignment_submit, { | |
"submission[assignment_id]" => id, | |
"submission[submitted_file]" => UploadIO.new(file, nil, path), | |
"submission[users]" => "" | |
}) | |
end | |
if response.kind_of? Net::HTTPFound | |
puts "Graded! #{response['Location']}" | |
else | |
puts "Error grading" | |
end | |
end | |
def list_assignments | |
response = make_api_request(:assignments) | |
assignments = parse_assignments(response.body) | |
puts "+------------------------+" | |
puts "| ID | Name |" | |
puts "+------------------------+" | |
assignments.each do |assignment| | |
puts "| %-4d | %-15s |" % [ assignment[:id], assignment[:name] ] | |
end | |
puts "+------------------------+" | |
end | |
FMT_ASSIGNMENTS = "//li[contains(@class, 'tab')]//a" | |
def parse_assignments(html) | |
nodes = Nokogiri::HTML(html).xpath(FMT_ASSIGNMENTS).to_ary | |
nodes.map do |node| | |
{ | |
:name => node.inner_text.strip, | |
:path => node['href'], | |
:id => node['href'].split('=')[1] | |
} | |
end | |
end | |
def authenticate_user(username, password) | |
response = make_api_request(:authenticate, { | |
"user[username]" => username, | |
"user[password]" => password | |
}) | |
if response.kind_of? Net::HTTPFound | |
cookie = response['Set-Cookie'] | |
marshal = Base64.decode64(cookie.split('; ')[0].split('=')[1]) | |
@authentication_cookie = cookie if marshal.match(/failed!/).nil? | |
end | |
authenticated? | |
end | |
def authenticated? | |
!(@authentication_cookie.nil?) | |
end | |
def make_api_request(path, args = nil) | |
node = API_NODES[path] | |
url = URI.parse(API_BASE + node[:path]) | |
request = nil | |
case node[:method] | |
when :get | |
request = Net::HTTP::Get.new url.path | |
request.set_form_data(args) unless args.nil? | |
when :post | |
request = Net::HTTP::Post.new url.path | |
request.set_form_data(args) unless args.nil? | |
when :post_multipart | |
request = Net::HTTP::Post::Multipart.new url.path, args | |
end | |
request['Cookie'] = @authentication_cookie if authenticated? | |
http = Net::HTTP.new(url.host, url.port) | |
http.use_ssl = true | |
http.verify_mode = OpenSSL::SSL::VERIFY_NONE | |
http.request(request) | |
end | |
end | |
class ArgumentParser | |
def initialize(args) | |
@arguments = {} | |
next_key = nil | |
args.each do |arg| | |
if next_key.nil? | |
case (arg = arg[1..-1]) | |
when '-send-file' | |
enforce_single_action_constraint | |
@arguments[:action] = :send_file | |
next_key = :file_path | |
when '-list-assignments' | |
enforce_single_action_constraint | |
@arguments[:action] = :list_assignments | |
when 'user', 'pass', 'id' | |
next_key = arg.to_sym | |
else | |
puts "Error: Invalid argument" | |
print_help | |
end | |
else | |
@arguments[next_key] = arg | |
next_key = nil | |
end | |
end | |
if @arguments[:action].nil? | |
puts "Error: no action specified" | |
print_help | |
end | |
if @arguments[:action] == :send_file && @arguments[:file_path].nil? | |
puts "Error: missing file path" | |
print_help | |
end | |
if @arguments[:action] == :send_file && @arguments[:id].nil? | |
puts "Error: missing assignment id" | |
print_help | |
end | |
if @arguments[:user].nil? || @arguments[:pass].nil? | |
puts "Error: missing username or password" | |
print_help | |
end | |
end | |
def [](value) | |
@arguments[value] | |
end | |
def enforce_single_action_constraint | |
if !@arguments[:action].nil? | |
puts "Error: #{arguments[:action]} already set as action" | |
print_help | |
end | |
end | |
def print_help | |
puts <<-text | |
Usage: plcsend --send-file <file-path> -id <assignment-id> | |
plcsend --list-assignments | |
All request also require authentication via the following flags. | |
-user [string] | |
Specifies the username to use for authentication. | |
-pass [string] | |
Specifies the password to use for authentication. | |
text | |
exit 1 | |
end | |
end | |
### ### | |
### main() ### | |
### ### | |
args = ArgumentParser.new(ARGV) | |
session = PLCServerSession.new | |
if !session.authenticate_user(args[:user], args[:pass]) | |
puts "Authentication failed!" | |
exit 1 | |
end | |
case args[:action] | |
when :send_file | |
session.send_file args[:file_path], args[:id] | |
when :list_assignments | |
session.list_assignments | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment