comet 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.rdoc +5 -0
- data/bin/comet +100 -0
- data/comet.rdoc +5 -0
- data/lib/comet/api.rb +74 -0
- data/lib/comet/challenge.rb +34 -0
- data/lib/comet/init.rb +42 -0
- data/lib/comet/version.rb +3 -0
- data/lib/comet.rb +4 -0
- metadata +115 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 29a39a8033839e24d0799a7ed0e8ef05ab1b6aec
|
4
|
+
data.tar.gz: c28253878dc3f2d2cef71e496fc808b390c2f25e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9113ef8c22817330545ec576b50cd2df077ff5163f4072edbde21ce4914352b8bee57e29ffdb9cfcd5e53f76695c67d7437ad58af967258ff017ef90e0e4b555
|
7
|
+
data.tar.gz: 97dc7dc5e468a8842556d80a99b82bfa7427379bf25b39e71f1ee29e2c270a937f7a5bf614a676987a85f146c3bf7b7c5ebc2c71dfb4f8f979bcb337f3f5f724
|
data/README.rdoc
ADDED
data/bin/comet
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'gli'
|
3
|
+
require 'yaml'
|
4
|
+
require 'comet'
|
5
|
+
|
6
|
+
include GLI::App
|
7
|
+
|
8
|
+
program_desc 'Test your Ruby skills! Download Ruby exercises and submit your solutions for grading.'
|
9
|
+
|
10
|
+
version Comet::VERSION
|
11
|
+
|
12
|
+
desc 'Initialize the current directory as a comet project directory'
|
13
|
+
skips_pre
|
14
|
+
command :init do |c|
|
15
|
+
c.action do |global_options, options, args|
|
16
|
+
answers = {}
|
17
|
+
|
18
|
+
print 'E-mail: '
|
19
|
+
answers['email'] = gets.chomp
|
20
|
+
|
21
|
+
print 'Token: '
|
22
|
+
answers['token'] = gets.chomp
|
23
|
+
|
24
|
+
print 'Server: '
|
25
|
+
answers['server'] = gets.chomp
|
26
|
+
|
27
|
+
Comet::Init.init_project_dir(Dir.pwd, answers)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
desc 'List the available challenges'
|
32
|
+
command :list do |c|
|
33
|
+
c.action do |global_options,options,args|
|
34
|
+
challenges = Comet::Challenge.list(@config)
|
35
|
+
|
36
|
+
if challenges.empty?
|
37
|
+
puts "No challenges available."
|
38
|
+
else
|
39
|
+
challenges.each do |challenge|
|
40
|
+
puts "#{challenge[:id]}: #{challenge[:name]}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
desc 'Download a challenge'
|
47
|
+
command :fetch do |c|
|
48
|
+
c.action do |global_options, options, args|
|
49
|
+
challenge_id = args.first
|
50
|
+
challenge = Comet::Challenge.find(@config, challenge_id)
|
51
|
+
directory = challenge.download
|
52
|
+
|
53
|
+
info = { 'id' => challenge_id.to_i, 'file_name' => "#{challenge.slug}.rb" }
|
54
|
+
info_file = File.join(directory, '.challenge')
|
55
|
+
File.write(info_file, info.to_yaml)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
desc 'Submit challenge'
|
60
|
+
command :submit do |c|
|
61
|
+
c.action do |global_options, options, args|
|
62
|
+
info_file = File.join(Dir.pwd, '.challenge')
|
63
|
+
|
64
|
+
if File.exists?(info_file)
|
65
|
+
info = YAML.load(File.read(info_file))
|
66
|
+
|
67
|
+
challenge_id = info['id']
|
68
|
+
solution_file = File.join(Dir.pwd, info['file_name'])
|
69
|
+
|
70
|
+
if File.exists?(solution_file)
|
71
|
+
Comet::API.submit(@config, challenge_id, solution_file)
|
72
|
+
else
|
73
|
+
puts "Missing solution file (#{solution_file})."
|
74
|
+
exit 1
|
75
|
+
end
|
76
|
+
else
|
77
|
+
puts "This is not a challenge directory."
|
78
|
+
exit 1
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
pre do |global,command,options,args|
|
84
|
+
@config = Comet::Init.find_config(Dir.pwd)
|
85
|
+
!@config.nil?
|
86
|
+
end
|
87
|
+
|
88
|
+
post do |global,command,options,args|
|
89
|
+
# Post logic here
|
90
|
+
# Use skips_post before a command to skip this
|
91
|
+
# block on that command only
|
92
|
+
end
|
93
|
+
|
94
|
+
on_error do |exception|
|
95
|
+
# Error logic here
|
96
|
+
# return false to skip default error handling
|
97
|
+
true
|
98
|
+
end
|
99
|
+
|
100
|
+
exit run(ARGV)
|
data/comet.rdoc
ADDED
data/lib/comet/api.rb
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module Comet
|
5
|
+
class API
|
6
|
+
def self.get_challenges(config)
|
7
|
+
response = request_with_token("http://#{config['server']}/api/v1/challenges.json",
|
8
|
+
config['token'])
|
9
|
+
|
10
|
+
results = JSON.parse(response.body, symbolize_names: true)
|
11
|
+
results[:challenges]
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.get_challenge(config, id)
|
15
|
+
response = request_with_token("http://#{config['server']}/api/v1/challenges/#{id}.json",
|
16
|
+
config['token'])
|
17
|
+
|
18
|
+
if response.code == '200'
|
19
|
+
results = JSON.parse(response.body, symbolize_names: true)
|
20
|
+
results[:challenge]
|
21
|
+
else
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.download_archive(download_link, dest)
|
27
|
+
uri = URI(download_link)
|
28
|
+
|
29
|
+
Net::HTTP.start(uri.host, uri.port) do |http|
|
30
|
+
resp = http.get(uri.path)
|
31
|
+
|
32
|
+
open(dest, 'wb') do |file|
|
33
|
+
file.write(resp.body)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
dest
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.submit(config, challenge_id, file_path)
|
41
|
+
uri = URI("http://#{config['server']}/api/v1/submissions.json")
|
42
|
+
req = Net::HTTP::Post.new(uri)
|
43
|
+
|
44
|
+
file_name = File.basename(file_path)
|
45
|
+
body = File.read(file_path)
|
46
|
+
|
47
|
+
req['Authorization'] = "Token #{config['token']}"
|
48
|
+
|
49
|
+
req.set_form_data({
|
50
|
+
'submission[challenge_id]' => challenge_id,
|
51
|
+
'submission[file_name]' => file_name,
|
52
|
+
'submission[body]' => body
|
53
|
+
})
|
54
|
+
|
55
|
+
res = Net::HTTP.start(uri.hostname, uri.port) do |http|
|
56
|
+
http.request(req)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def self.request_with_token(url, token)
|
63
|
+
uri = URI(url)
|
64
|
+
|
65
|
+
request = Net::HTTP::Get.new(uri)
|
66
|
+
request['Authorization'] = "Token #{token}"
|
67
|
+
response = Net::HTTP.start(uri.hostname, uri.port) do |http|
|
68
|
+
http.request(request)
|
69
|
+
end
|
70
|
+
|
71
|
+
response
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class Comet::Challenge
|
2
|
+
attr_reader :id, :name, :slug, :download_link, :basedir
|
3
|
+
|
4
|
+
def initialize(params)
|
5
|
+
@id = params[:id]
|
6
|
+
@name = params[:name]
|
7
|
+
@slug = params[:slug]
|
8
|
+
@download_link = params[:download_link]
|
9
|
+
@basedir = params[:basedir]
|
10
|
+
end
|
11
|
+
|
12
|
+
def download
|
13
|
+
archive = Comet::API.download_archive(download_link, File.join(basedir, "#{slug}.tar.gz"))
|
14
|
+
`tar zxf #{archive} -C #{basedir}`
|
15
|
+
File.delete(archive)
|
16
|
+
File.join(basedir, slug)
|
17
|
+
end
|
18
|
+
|
19
|
+
class << self
|
20
|
+
def list(config)
|
21
|
+
Comet::API.get_challenges(config)
|
22
|
+
end
|
23
|
+
|
24
|
+
def find(config, id)
|
25
|
+
challenge_info = Comet::API.get_challenge(config, id)
|
26
|
+
|
27
|
+
if challenge_info.nil?
|
28
|
+
raise ArgumentError.new("Could not find challenge with id = #{id}")
|
29
|
+
else
|
30
|
+
Comet::Challenge.new(challenge_info.merge({ basedir: config['basedir'] }))
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/comet/init.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Comet
|
4
|
+
class Init
|
5
|
+
class << self
|
6
|
+
def find_config(dir)
|
7
|
+
config_file = File.join(dir, '.comet')
|
8
|
+
|
9
|
+
if File.exists?(config_file)
|
10
|
+
config = YAML.load(File.read(config_file))
|
11
|
+
config.merge({ 'basedir' => dir })
|
12
|
+
else
|
13
|
+
parent_dir = File.dirname(dir)
|
14
|
+
|
15
|
+
if parent_dir != '/' && parent_dir != '.'
|
16
|
+
find_config(parent_dir)
|
17
|
+
else
|
18
|
+
nil
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def init_project_dir(dirname, user_answers)
|
24
|
+
config_file = File.join(dirname, '.comet')
|
25
|
+
|
26
|
+
unless File.exists?(config_file)
|
27
|
+
config = {
|
28
|
+
'email' => user_answers['email'],
|
29
|
+
'token' => user_answers['token'],
|
30
|
+
'server' => user_answers['server']
|
31
|
+
}
|
32
|
+
|
33
|
+
File.write(config_file, config.to_yaml)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/comet.rb
ADDED
metadata
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: comet
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Adam Sheehan
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-02-11 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
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: rdoc
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: gli
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 2.8.1
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 2.8.1
|
69
|
+
description:
|
70
|
+
email: adam.sheehan@launchacademy.com
|
71
|
+
executables:
|
72
|
+
- comet
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files:
|
75
|
+
- README.rdoc
|
76
|
+
- comet.rdoc
|
77
|
+
files:
|
78
|
+
- bin/comet
|
79
|
+
- lib/comet.rb
|
80
|
+
- lib/comet/api.rb
|
81
|
+
- lib/comet/challenge.rb
|
82
|
+
- lib/comet/init.rb
|
83
|
+
- lib/comet/version.rb
|
84
|
+
- README.rdoc
|
85
|
+
- comet.rdoc
|
86
|
+
homepage: http://launchacademy.com
|
87
|
+
licenses: []
|
88
|
+
metadata: {}
|
89
|
+
post_install_message:
|
90
|
+
rdoc_options:
|
91
|
+
- --title
|
92
|
+
- comet
|
93
|
+
- --main
|
94
|
+
- README.rdoc
|
95
|
+
- -ri
|
96
|
+
require_paths:
|
97
|
+
- lib
|
98
|
+
- lib
|
99
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - '>='
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
109
|
+
requirements: []
|
110
|
+
rubyforge_project:
|
111
|
+
rubygems_version: 2.1.11
|
112
|
+
signing_key:
|
113
|
+
specification_version: 4
|
114
|
+
summary: Command-line interface for downloading and submitting code exercises.
|
115
|
+
test_files: []
|