frecon 0.5.0 → 0.5.2
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 +4 -4
- data/Gemfile +4 -0
- data/Rakefile +15 -0
- data/lib/frecon.rb +12 -2
- data/lib/frecon/base/bson.rb +9 -0
- data/lib/frecon/base/variables.rb +9 -1
- data/lib/frecon/configuration.rb +25 -1
- data/lib/frecon/configuration_file.rb +17 -1
- data/lib/frecon/console.rb +7 -1
- data/lib/frecon/controller.rb +94 -3
- data/lib/frecon/controllers/competitions_controller.rb +1 -0
- data/lib/frecon/controllers/dump_controller.rb +12 -0
- data/lib/frecon/controllers/matches_controller.rb +1 -0
- data/lib/frecon/controllers/participations_controller.rb +1 -0
- data/lib/frecon/controllers/records_controller.rb +1 -0
- data/lib/frecon/controllers/robots_controller.rb +1 -0
- data/lib/frecon/controllers/teams_controller.rb +1 -1
- data/lib/frecon/database.rb +9 -1
- data/lib/frecon/match_number.rb +69 -3
- data/lib/frecon/model.rb +60 -5
- data/lib/frecon/models/competition.rb +4 -0
- data/lib/frecon/models/match.rb +4 -0
- data/lib/frecon/models/participation.rb +3 -0
- data/lib/frecon/models/record.rb +4 -0
- data/lib/frecon/models/robot.rb +4 -0
- data/lib/frecon/models/team.rb +10 -1
- data/lib/frecon/mongoid/criteria.rb +42 -1
- data/lib/frecon/position.rb +50 -7
- data/lib/frecon/request_error.rb +8 -0
- data/lib/frecon/routes.rb +14 -0
- data/lib/frecon/server.rb +24 -1
- metadata +45 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4e2c810e2a8cf4f910ac9a90d52a449b61285df9
|
|
4
|
+
data.tar.gz: 8a3f9339a0b6539ec355458f8e1b9e7aa3a995da
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 52ce69ae4af6d7137426fd79a6ea39deffdc0d71900a18cbff137ee986a6ff74dfad0aad45284dbc5840629670088e9b1c8c5a50911822382d354a7b843d22ed
|
|
7
|
+
data.tar.gz: 362cea6a6e6110246ba69320b856d9439c52c0c14c659734f61eeb78fadc0f5bbdb25127239b10bd3ffc9646498ca0f5cffc780fba4ccda21db6883b30ad8152
|
data/Gemfile
ADDED
data/Rakefile
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require "yard"
|
|
2
|
+
|
|
3
|
+
YARD::Config.load_plugin('tomdoc')
|
|
4
|
+
YARD::Config.load_plugin('mongoid')
|
|
5
|
+
|
|
6
|
+
namespace :docs do
|
|
7
|
+
YARD::Rake::YardocTask.new :generate do |task|
|
|
8
|
+
task.files = ['lib/**/*.rb', 'bin/**/*']
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
YARD::Rake::YardocTask.new :list_undoc do |task|
|
|
12
|
+
task.files = ['lib/**/*.rb', 'bin/**/*']
|
|
13
|
+
task.stats_options = ['--list-undoc']
|
|
14
|
+
end
|
|
15
|
+
end
|
data/lib/frecon.rb
CHANGED
|
@@ -11,10 +11,20 @@ require "mongoid"
|
|
|
11
11
|
|
|
12
12
|
require "frecon/base"
|
|
13
13
|
|
|
14
|
+
require "frecon/controller"
|
|
15
|
+
require "frecon/controllers"
|
|
16
|
+
require "frecon/model"
|
|
17
|
+
require "frecon/models"
|
|
18
|
+
require "frecon/scraper"
|
|
19
|
+
require "frecon/scrapers"
|
|
20
|
+
|
|
14
21
|
require "frecon/configuration"
|
|
15
22
|
require "frecon/configuration_file"
|
|
23
|
+
require "frecon/match_number"
|
|
24
|
+
require "frecon/position"
|
|
25
|
+
require "frecon/request_error"
|
|
26
|
+
require "frecon/routes"
|
|
27
|
+
|
|
16
28
|
require "frecon/database"
|
|
17
29
|
require "frecon/server"
|
|
18
30
|
require "frecon/console"
|
|
19
|
-
|
|
20
|
-
require "frecon/scrapers"
|
data/lib/frecon/base/bson.rb
CHANGED
|
@@ -7,8 +7,17 @@
|
|
|
7
7
|
# license with this program. If not, please see
|
|
8
8
|
# <http://opensource.org/licenses/MIT>.
|
|
9
9
|
|
|
10
|
+
# Public: An extension for the BSON module.
|
|
10
11
|
module BSON
|
|
12
|
+
# Public: A monkey-patch for the BSON::ObjectId class which introduces an
|
|
13
|
+
# #as_json method.
|
|
11
14
|
class ObjectId
|
|
15
|
+
# Public: Get produce a JSON representation of this ObjectId.
|
|
16
|
+
#
|
|
17
|
+
# Since we don't want to produce a JSON Object for every ID, this method
|
|
18
|
+
# instead just returns the String _id value within this object.
|
|
19
|
+
#
|
|
20
|
+
# Returns a String containing the value of this ObjectId.
|
|
12
21
|
def as_json(*args)
|
|
13
22
|
to_s
|
|
14
23
|
end
|
|
@@ -7,15 +7,23 @@
|
|
|
7
7
|
# license with this program. If not, please see
|
|
8
8
|
# <http://opensource.org/licenses/MIT>.
|
|
9
9
|
|
|
10
|
+
# Public: The FReCon API module.
|
|
10
11
|
module FReCon
|
|
11
|
-
|
|
12
|
+
# Public: A String representing the current version of FReCon.
|
|
13
|
+
VERSION = "0.5.2"
|
|
12
14
|
|
|
13
15
|
@environment_variable = :development
|
|
14
16
|
|
|
17
|
+
# Public: Returns the current environment.
|
|
15
18
|
def self.environment
|
|
16
19
|
@environment_variable
|
|
17
20
|
end
|
|
18
21
|
|
|
22
|
+
# Public: Sets the environment.
|
|
23
|
+
#
|
|
24
|
+
# arg - The new environment.
|
|
25
|
+
#
|
|
26
|
+
# Returns the result from setting the current environment.
|
|
19
27
|
def self.environment=(arg)
|
|
20
28
|
@environment_variable = arg
|
|
21
29
|
end
|
data/lib/frecon/configuration.rb
CHANGED
|
@@ -10,13 +10,23 @@
|
|
|
10
10
|
require "frecon/configuration_file"
|
|
11
11
|
|
|
12
12
|
module FReCon
|
|
13
|
+
# Public: A wrapper to allow the manipulation of configurations.
|
|
13
14
|
class Configuration < Hash
|
|
15
|
+
# Public: Initialize a Configuration.
|
|
16
|
+
#
|
|
17
|
+
# data - a Hash representing the data.
|
|
14
18
|
def initialize(data)
|
|
15
19
|
data.each do |key, value|
|
|
16
20
|
self[key] = value
|
|
17
21
|
end
|
|
18
22
|
end
|
|
19
23
|
|
|
24
|
+
# Public: Convert self to a Hash.
|
|
25
|
+
#
|
|
26
|
+
# Recursively converts instances of Configuration within self
|
|
27
|
+
# to hashes by calling this method.
|
|
28
|
+
#
|
|
29
|
+
# Returns a Hash representing self.
|
|
20
30
|
def to_h
|
|
21
31
|
hash = {}
|
|
22
32
|
|
|
@@ -32,6 +42,11 @@ module FReCon
|
|
|
32
42
|
hash
|
|
33
43
|
end
|
|
34
44
|
|
|
45
|
+
# Public: Merge with another Configuration.
|
|
46
|
+
#
|
|
47
|
+
# Sets all key-value pairs within Configuration to the same within self.
|
|
48
|
+
#
|
|
49
|
+
# other - A Configuration or Hash to be merged with.
|
|
35
50
|
def merge(other)
|
|
36
51
|
case other
|
|
37
52
|
when Configuration, Hash
|
|
@@ -49,11 +64,20 @@ module FReCon
|
|
|
49
64
|
end
|
|
50
65
|
end
|
|
51
66
|
|
|
67
|
+
# Public: Constructs a configuration.
|
|
68
|
+
#
|
|
69
|
+
# options - A Hash containing various configurations.
|
|
70
|
+
# :default_configuration - The default configuration's values
|
|
71
|
+
# :system_configuration - The system's configuration's values
|
|
72
|
+
# :user_configuration - The user's configuration's values
|
|
73
|
+
# :argument_configuration - The configuration values from command-line arguments
|
|
74
|
+
#
|
|
75
|
+
# Returns a Configuration generated by merging all of the given
|
|
76
|
+
# configurations together.
|
|
52
77
|
def self.construct!(default_configuration: ConfigurationFile.default.read,
|
|
53
78
|
system_configuration: ConfigurationFile.system.read,
|
|
54
79
|
user_configuration: ConfigurationFile.user.read,
|
|
55
80
|
argument_configuration: nil)
|
|
56
|
-
|
|
57
81
|
configuration_hierarchy = [default_configuration, system_configuration, user_configuration, argument_configuration]
|
|
58
82
|
|
|
59
83
|
configuration = Configuration.new({})
|
|
@@ -11,13 +11,23 @@ require "yaml"
|
|
|
11
11
|
require "frecon/configuration"
|
|
12
12
|
|
|
13
13
|
module FReCon
|
|
14
|
+
# Public: A class to handle configuration files.
|
|
14
15
|
class ConfigurationFile
|
|
16
|
+
# Public: The filename for the file.
|
|
15
17
|
attr_accessor :filename
|
|
16
18
|
|
|
19
|
+
# Public: Initialize a ConfigurationFile.
|
|
20
|
+
#
|
|
21
|
+
# filename - The name of the file.
|
|
17
22
|
def initialize(filename)
|
|
18
23
|
@filename = filename
|
|
19
24
|
end
|
|
20
25
|
|
|
26
|
+
# Public: Read from the file and generate a Configuration
|
|
27
|
+
# from the YAML data therein.
|
|
28
|
+
#
|
|
29
|
+
# Returns a Configuration representing the file's data or nil if it didn't
|
|
30
|
+
# exist.
|
|
21
31
|
def read
|
|
22
32
|
begin
|
|
23
33
|
data = open(@filename, "rb") do |io|
|
|
@@ -30,16 +40,22 @@ module FReCon
|
|
|
30
40
|
end
|
|
31
41
|
end
|
|
32
42
|
|
|
43
|
+
# Public: Create a new ConfigurationFile corresponding to the default
|
|
44
|
+
# defaults configuration location.
|
|
33
45
|
def self.default
|
|
34
46
|
self.new(File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "config", "default.yml")))
|
|
35
47
|
end
|
|
36
48
|
|
|
49
|
+
# Public: Create a new ConfigurationFile corresponding to the default
|
|
50
|
+
# system configuration location.
|
|
37
51
|
def self.system
|
|
38
52
|
self.new(File.join("", "etc", "frecon", "config.yml"))
|
|
39
53
|
end
|
|
40
54
|
|
|
55
|
+
# Public: Create a new ConfigurationFile corresponding to the default
|
|
56
|
+
# user configuration location.
|
|
41
57
|
def self.user
|
|
42
|
-
self.new(File.join(Dir.home, "config", "frecon.yml"))
|
|
58
|
+
self.new(File.join(Dir.home, ".config", "frecon.yml"))
|
|
43
59
|
end
|
|
44
60
|
end
|
|
45
61
|
end
|
data/lib/frecon/console.rb
CHANGED
|
@@ -13,11 +13,17 @@ require "frecon/database"
|
|
|
13
13
|
require "frecon/server"
|
|
14
14
|
|
|
15
15
|
module FReCon
|
|
16
|
+
# Public: The wrapper system for a pry console.
|
|
16
17
|
class Console
|
|
18
|
+
# Public: Starts the FReCon console.
|
|
19
|
+
#
|
|
20
|
+
# :configuration - The Configuration to use when starting the console.
|
|
21
|
+
#
|
|
22
|
+
# Returns the result of running pry on FReCon.
|
|
17
23
|
def self.start(configuration: Configuration.construct!)
|
|
18
24
|
environment = configuration["frecon"]["console"]["environment"]
|
|
19
25
|
mongoid = configuration["frecon"]["database"]["mongoid"]
|
|
20
|
-
Database.setup(environment
|
|
26
|
+
Database.setup(environment, mongoid)
|
|
21
27
|
|
|
22
28
|
require "pry"
|
|
23
29
|
|
data/lib/frecon/controller.rb
CHANGED
|
@@ -10,30 +10,54 @@
|
|
|
10
10
|
require "frecon/base"
|
|
11
11
|
|
|
12
12
|
module FReCon
|
|
13
|
+
# Public: A base class to represent a controller.
|
|
13
14
|
class Controller
|
|
15
|
+
# Public: Converts the class's name to a Model name.
|
|
16
|
+
#
|
|
17
|
+
# Returns a Symbol that is the Model name.
|
|
14
18
|
def self.model_name
|
|
15
19
|
# Removes the namespace "FReCon::" and "Controller" from
|
|
16
20
|
# the class name, then singularizes the result.
|
|
17
21
|
self.name.gsub(/FReCon::|Controller\Z/, "").singularize
|
|
18
22
|
end
|
|
19
23
|
|
|
24
|
+
# Public: Converts the class's name to a Model.
|
|
25
|
+
#
|
|
26
|
+
# Returns the Model's class.
|
|
20
27
|
def self.model
|
|
21
28
|
# Removes the trailing "Controller" from the class name,
|
|
22
29
|
# singularizes the result, and turns it into the class.
|
|
23
30
|
self.name.gsub(/Controller\Z/, "").singularize.constantize
|
|
24
31
|
end
|
|
25
32
|
|
|
26
|
-
#
|
|
27
|
-
#
|
|
33
|
+
# Public: Find a model.
|
|
34
|
+
#
|
|
35
|
+
# params - A Hash containing the parameters. This should contain an
|
|
36
|
+
# 'id' key, which is deleted and used for the find.
|
|
37
|
+
#
|
|
38
|
+
# Returns either the found model value or nil.
|
|
28
39
|
def self.find_model(params)
|
|
29
40
|
model.find params.delete("id")
|
|
30
41
|
end
|
|
31
42
|
|
|
32
|
-
#
|
|
43
|
+
# Public: Generate a could-not-find message.
|
|
44
|
+
#
|
|
45
|
+
# value - The value that was tested.
|
|
46
|
+
# attribute - The attribute that was used for the search.
|
|
47
|
+
# model - The model that the search was performed upon.
|
|
48
|
+
#
|
|
49
|
+
# Returns a String containing the error message.
|
|
33
50
|
def self.could_not_find(value, attribute = "id", model = model_name.downcase)
|
|
34
51
|
"Could not find #{model} of #{attribute} #{value}!"
|
|
35
52
|
end
|
|
36
53
|
|
|
54
|
+
# Public: Process a JSON request.
|
|
55
|
+
#
|
|
56
|
+
# request - The internal Sinatra request object that is available to
|
|
57
|
+
# request handling.
|
|
58
|
+
#
|
|
59
|
+
# Returns a Hash corresponding to the request's body.
|
|
60
|
+
# Raises a RequestError if the JSON parse fails.
|
|
37
61
|
def self.process_json_request(request)
|
|
38
62
|
# Rewind the request body (an IO object)
|
|
39
63
|
# in case someone else has already played
|
|
@@ -49,6 +73,20 @@ module FReCon
|
|
|
49
73
|
post_data
|
|
50
74
|
end
|
|
51
75
|
|
|
76
|
+
# Public: Process a creation request (HTTP POST)
|
|
77
|
+
#
|
|
78
|
+
# If `post_data` is an Array, iterates through the array and calls itself
|
|
79
|
+
# with each element within. Otherwise, performs the creation using
|
|
80
|
+
# the attribute key-value pairings within the `post_data`.
|
|
81
|
+
#
|
|
82
|
+
# request - The internal Sinatra request object that is available to
|
|
83
|
+
# request handling.
|
|
84
|
+
# params - The internal params Hash that is available to request
|
|
85
|
+
# handling.
|
|
86
|
+
# post_data - The data that was sent in the request body.
|
|
87
|
+
#
|
|
88
|
+
# Returns an Array, a formatted response that can be passed back through
|
|
89
|
+
# Sinatra's request processing.
|
|
52
90
|
def self.create(request, params, post_data = nil)
|
|
53
91
|
post_data ||= process_json_request request
|
|
54
92
|
|
|
@@ -85,6 +123,19 @@ module FReCon
|
|
|
85
123
|
end
|
|
86
124
|
end
|
|
87
125
|
|
|
126
|
+
# Public: Process an update request (HTTP PUT)
|
|
127
|
+
#
|
|
128
|
+
# Processes the JSON request, finds the model, then updates it.
|
|
129
|
+
#
|
|
130
|
+
# request - The internal Sinatra request object that is available to
|
|
131
|
+
# request handling.
|
|
132
|
+
# params - The internal params Hash that is available to request
|
|
133
|
+
# handling.
|
|
134
|
+
# post_data - The data that was sent in the request body.
|
|
135
|
+
#
|
|
136
|
+
# Returns a String with the JSON representation of the model.
|
|
137
|
+
# Raises a RequestError if the request is malformed or if the attributes
|
|
138
|
+
# can't be updated.
|
|
88
139
|
def self.update(request, params, post_data = nil)
|
|
89
140
|
raise RequestError.new(400, "Must supply a #{model_name.downcase} id!") unless params[:id]
|
|
90
141
|
|
|
@@ -101,6 +152,19 @@ module FReCon
|
|
|
101
152
|
end
|
|
102
153
|
end
|
|
103
154
|
|
|
155
|
+
# Public: Process a deletion request (HTTP DELETE)
|
|
156
|
+
#
|
|
157
|
+
# Processes the JSON request, finds the model, then deletes it.
|
|
158
|
+
#
|
|
159
|
+
# request - The internal Sinatra request object that is available to
|
|
160
|
+
# request handling.
|
|
161
|
+
# params - The internal params Hash that is available to request
|
|
162
|
+
# handling.
|
|
163
|
+
# post_data - The data that was sent in the request body.
|
|
164
|
+
#
|
|
165
|
+
# Returns 204 if successful.
|
|
166
|
+
# Raises a RequestError if the request is malformed or if the model can't be
|
|
167
|
+
# destroyed
|
|
104
168
|
def self.delete(params)
|
|
105
169
|
@model = find_model params
|
|
106
170
|
|
|
@@ -115,6 +179,20 @@ module FReCon
|
|
|
115
179
|
end
|
|
116
180
|
end
|
|
117
181
|
|
|
182
|
+
# Public: Process a show request (HTTP GET) for a specific instance of a
|
|
183
|
+
# model.
|
|
184
|
+
#
|
|
185
|
+
# Processes the JSON request, finds the model, then shows it.
|
|
186
|
+
#
|
|
187
|
+
# request - The internal Sinatra request object that is available to
|
|
188
|
+
# request handling.
|
|
189
|
+
# params - The internal params Hash that is available to request
|
|
190
|
+
# handling.
|
|
191
|
+
# post_data - The data that was sent in the request body.
|
|
192
|
+
#
|
|
193
|
+
# Returns a String with the JSON representation of the model.
|
|
194
|
+
# Raises a RequestError if the request is malformed or if the model can't be
|
|
195
|
+
# found.
|
|
118
196
|
def self.show(params)
|
|
119
197
|
@model = find_model params
|
|
120
198
|
|
|
@@ -125,6 +203,19 @@ module FReCon
|
|
|
125
203
|
end
|
|
126
204
|
end
|
|
127
205
|
|
|
206
|
+
# Public: Process an index request (HTTP GET) for all instances of a model.
|
|
207
|
+
#
|
|
208
|
+
# Processes the JSON request, and returns a filtered list of all of the
|
|
209
|
+
# models.
|
|
210
|
+
#
|
|
211
|
+
# request - The internal Sinatra request object that is available to
|
|
212
|
+
# request handling.
|
|
213
|
+
# params - The internal params Hash that is available to request
|
|
214
|
+
# handling.
|
|
215
|
+
# post_data - The data that was sent in the request body.
|
|
216
|
+
#
|
|
217
|
+
# Returns a String with the JSON representation of the list of models.
|
|
218
|
+
# Raises a RequestError if the request is malformed.
|
|
128
219
|
def self.index(params)
|
|
129
220
|
if params.empty?
|
|
130
221
|
@models = model.all
|
|
@@ -11,7 +11,11 @@ require "json"
|
|
|
11
11
|
require "frecon/models"
|
|
12
12
|
|
|
13
13
|
module FReCon
|
|
14
|
+
# Public: The Dump controller.
|
|
14
15
|
class DumpController
|
|
16
|
+
# Public: Creates a dump.
|
|
17
|
+
#
|
|
18
|
+
# Returns a String containing a dump of the database.
|
|
15
19
|
def self.full(params)
|
|
16
20
|
dump = {}
|
|
17
21
|
|
|
@@ -30,6 +34,14 @@ module FReCon
|
|
|
30
34
|
dump.to_json
|
|
31
35
|
end
|
|
32
36
|
|
|
37
|
+
# Public: Converts a Model's name to a dump-compliant name.
|
|
38
|
+
#
|
|
39
|
+
# Examples
|
|
40
|
+
#
|
|
41
|
+
# DumpController.dump_compliant_name(FReCon::Team)
|
|
42
|
+
# # => "teams"
|
|
43
|
+
#
|
|
44
|
+
# Returns a dump-compliant string.
|
|
33
45
|
def self.dump_compliant_name(model)
|
|
34
46
|
model.name.gsub(/FReCon::/, "").downcase.pluralize
|
|
35
47
|
end
|
data/lib/frecon/database.rb
CHANGED
|
@@ -18,8 +18,16 @@ require "yaml"
|
|
|
18
18
|
require "frecon/models"
|
|
19
19
|
|
|
20
20
|
module FReCon
|
|
21
|
+
# Public: A system to set up the database.
|
|
21
22
|
class Database
|
|
22
|
-
|
|
23
|
+
# Public: Set up the database.
|
|
24
|
+
#
|
|
25
|
+
# environment - Symbol containing environment to start the database in.
|
|
26
|
+
# mongoid - Hash containing the configuration for Mongoid. If not
|
|
27
|
+
# present, the lib/frecon/mongoid.yml file is given to
|
|
28
|
+
# Mongoid.load!. If present, the Hash is dumped to a
|
|
29
|
+
# tempfile which is given to Mongoid.load!.
|
|
30
|
+
def self.setup(environment = FReCon.environment, mongoid = nil)
|
|
23
31
|
if mongoid.is_a?(Hash)
|
|
24
32
|
mongoid_tempfile = Tempfile.new("FReCon")
|
|
25
33
|
|
data/lib/frecon/match_number.rb
CHANGED
|
@@ -10,13 +10,46 @@
|
|
|
10
10
|
require "frecon/base"
|
|
11
11
|
|
|
12
12
|
module FReCon
|
|
13
|
+
# Public: A wrapper to handle converting match numbers and storing them.
|
|
13
14
|
class MatchNumber
|
|
15
|
+
# Public: All of the possible match types for a MatchNumber to have.
|
|
14
16
|
POSSIBLE_TYPES = [:practice, :qualification, :quarterfinal, :semifinal, :final]
|
|
15
|
-
ELIMINATION_TYPES = [:quarterfinal, :semifinal, :final]
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
# Public: All of the elimination types for a MatchNumber to have.
|
|
19
|
+
ELIMINATION_TYPES = [:quarterfinal, :semifinal, :final]
|
|
18
20
|
|
|
19
|
-
#
|
|
21
|
+
# Public: The numerical part of the match number
|
|
22
|
+
#
|
|
23
|
+
# Examples
|
|
24
|
+
#
|
|
25
|
+
# match_number = MatchNumber.new('qm2')
|
|
26
|
+
# match_number.number
|
|
27
|
+
# # => 2
|
|
28
|
+
attr_reader :number
|
|
29
|
+
|
|
30
|
+
# Public: The round part of the match number
|
|
31
|
+
#
|
|
32
|
+
# Examples
|
|
33
|
+
#
|
|
34
|
+
# match_number = MatchNumber.new('qf1m2r3')
|
|
35
|
+
# match_number.round
|
|
36
|
+
# # => 2
|
|
37
|
+
attr_reader :round
|
|
38
|
+
|
|
39
|
+
# Public: The type of the match.
|
|
40
|
+
#
|
|
41
|
+
# Examples
|
|
42
|
+
#
|
|
43
|
+
# match_number = MatchNumber.new('qf1m2r3')
|
|
44
|
+
# match_number.type
|
|
45
|
+
# # => :quarterfinal
|
|
46
|
+
attr_reader :type
|
|
47
|
+
|
|
48
|
+
# Public: Convert a stored match number to a MatchNumber object.
|
|
49
|
+
#
|
|
50
|
+
# object - String representation of a match number (mongoized)
|
|
51
|
+
#
|
|
52
|
+
# Returns MatchNumber parsed from object.
|
|
20
53
|
def self.demongoize(object)
|
|
21
54
|
# `object' should *always* be a string (since MatchNumber#mongoize returns a
|
|
22
55
|
# String which is what is stored in the database)
|
|
@@ -25,6 +58,15 @@ module FReCon
|
|
|
25
58
|
MatchNumber.new(object)
|
|
26
59
|
end
|
|
27
60
|
|
|
61
|
+
# Public: Convert a MatchNumber object to a storable string representation.
|
|
62
|
+
#
|
|
63
|
+
# object - A MatchNumber, String, or Hash. If MatchNumber, run #mongoize on
|
|
64
|
+
# it. If String, create a new MatchNumber object for it, then run
|
|
65
|
+
# #mongoize on it. If Hash, convert its keys to symbols, then
|
|
66
|
+
# pull out the :alliance and :number keys to generate a
|
|
67
|
+
# MatchNumber.
|
|
68
|
+
#
|
|
69
|
+
# Returns String containing the mongo-ready value for the representation.
|
|
28
70
|
def self.mongoize(object)
|
|
29
71
|
case object
|
|
30
72
|
when MatchNumber
|
|
@@ -36,6 +78,16 @@ module FReCon
|
|
|
36
78
|
end
|
|
37
79
|
end
|
|
38
80
|
|
|
81
|
+
# Public: Convert a MatchNumber object to a storable string representation
|
|
82
|
+
# for queries.
|
|
83
|
+
#
|
|
84
|
+
# object - A MatchNumber, String, or Hash. If MatchNumber, run #mongoize on
|
|
85
|
+
# it. If String, create a new MatchNumber object for it, then run
|
|
86
|
+
# #mongoize on it. If Hash, convert its keys to symbols, then
|
|
87
|
+
# pull out the :alliance and :number keys to generate a
|
|
88
|
+
# MatchNumber.
|
|
89
|
+
#
|
|
90
|
+
# Returns String containing the mongo-ready value for the representation.
|
|
39
91
|
def self.evolve(object)
|
|
40
92
|
case object
|
|
41
93
|
when MatchNumber
|
|
@@ -47,6 +99,9 @@ module FReCon
|
|
|
47
99
|
end
|
|
48
100
|
end
|
|
49
101
|
|
|
102
|
+
# Public: Convert to a storable string representation.
|
|
103
|
+
#
|
|
104
|
+
# Returns String representing the MatchNumber's data.
|
|
50
105
|
def mongoize
|
|
51
106
|
to_s
|
|
52
107
|
end
|
|
@@ -156,6 +211,9 @@ module FReCon
|
|
|
156
211
|
end
|
|
157
212
|
end
|
|
158
213
|
|
|
214
|
+
# Public: Convert to a String.
|
|
215
|
+
#
|
|
216
|
+
# Returns String representing the match number data.
|
|
159
217
|
def to_s
|
|
160
218
|
type_string = case @type
|
|
161
219
|
when :practice
|
|
@@ -175,30 +233,38 @@ module FReCon
|
|
|
175
233
|
"#{type_string}#{@round}#{match_string}#{replay_string}"
|
|
176
234
|
end
|
|
177
235
|
|
|
236
|
+
# Public: Determine if MatchNumber represents a replay.
|
|
178
237
|
def replay?
|
|
179
238
|
!@replay_number.nil? && @replay_number > 0
|
|
180
239
|
end
|
|
181
240
|
|
|
241
|
+
# Public: Determine if MatchNumber represents a practice match.
|
|
182
242
|
def practice?
|
|
183
243
|
@type == :practice
|
|
184
244
|
end
|
|
185
245
|
|
|
246
|
+
# Public: Determine if MatchNumber represents a qualification match.
|
|
186
247
|
def qualification?
|
|
187
248
|
@type == :qualification
|
|
188
249
|
end
|
|
189
250
|
|
|
251
|
+
# Public: Determine if MatchNumber represents a quarterfinal match.
|
|
190
252
|
def quarterfinal?
|
|
191
253
|
@type == :quarterfinal
|
|
192
254
|
end
|
|
193
255
|
|
|
256
|
+
# Public: Determine if MatchNumber represents a semifinal match.
|
|
194
257
|
def semifinal?
|
|
195
258
|
@type == :semifinal
|
|
196
259
|
end
|
|
197
260
|
|
|
261
|
+
# Public: Determine if MatchNumber represents a final match.
|
|
198
262
|
def final?
|
|
199
263
|
@type == :final
|
|
200
264
|
end
|
|
201
265
|
|
|
266
|
+
# Public: Determine if MatchNumber represents a match of any elimination
|
|
267
|
+
# type.
|
|
202
268
|
def elimination?
|
|
203
269
|
ELIMINATION_TYPES.include?(@type)
|
|
204
270
|
end
|
data/lib/frecon/model.rb
CHANGED
|
@@ -11,46 +11,101 @@ require "mongoid"
|
|
|
11
11
|
require "frecon/mongoid/criteria"
|
|
12
12
|
|
|
13
13
|
module FReCon
|
|
14
|
+
# Public: A base class designed to assist with creating MongoDB Models
|
|
15
|
+
# elsewhere in the project.
|
|
14
16
|
class Model
|
|
17
|
+
# Public: Bootstraps inheritors of this class as working
|
|
18
|
+
# Models, also providing class methods for them to use.
|
|
19
|
+
#
|
|
20
|
+
# child - The class that is inheriting this class.
|
|
21
|
+
#
|
|
22
|
+
# Returns the result of bootstrapping the child.
|
|
15
23
|
def self.inherited(child)
|
|
16
24
|
child.class_eval do
|
|
25
|
+
# Include the various Mongoid modules that we want to use.
|
|
17
26
|
include Mongoid::Document
|
|
18
27
|
include Mongoid::Timestamps
|
|
19
28
|
include Mongoid::Attributes::Dynamic
|
|
20
29
|
|
|
30
|
+
# Ensure that no invalid relations exist.
|
|
21
31
|
validate :no_invalid_relations
|
|
22
32
|
|
|
23
33
|
self.class_variable_set(:@@attributes, [])
|
|
24
34
|
|
|
35
|
+
# Public: Register a method as a routable relation method.
|
|
36
|
+
#
|
|
37
|
+
# Models can register relation methods that they have defined
|
|
38
|
+
# (e.g. team.robots) as routable methods. The Routes module reads
|
|
39
|
+
# these routable relations, and generates routes for them.
|
|
40
|
+
#
|
|
41
|
+
# method - A Symbol containing the name of the relation method.
|
|
42
|
+
# attribute - A String representing the attribute that the Routes
|
|
43
|
+
# module should route this method under.
|
|
44
|
+
#
|
|
45
|
+
# Examples
|
|
46
|
+
#
|
|
47
|
+
# # (Taken from the Team model)
|
|
48
|
+
# register_routable_relation :matches, "matches"
|
|
49
|
+
#
|
|
50
|
+
# Returns the result of pushing an object to class's attributes
|
|
51
|
+
# class variable.
|
|
25
52
|
def self.register_routable_relation(method, attribute)
|
|
26
53
|
self.class_variable_get(:@@attributes) << {method: method, type: :relation, attribute: attribute}
|
|
27
54
|
end
|
|
28
55
|
|
|
56
|
+
# Public: Register a method as a routable attribute method.
|
|
57
|
+
#
|
|
58
|
+
# Models can register attribute methods that they have defined
|
|
59
|
+
# (e.g. team.number) as attribute methods. The Routes module reads
|
|
60
|
+
# these routable attributes, and generates routes for them.
|
|
61
|
+
#
|
|
62
|
+
# method - A Symbol containing the name of the attribute method.
|
|
63
|
+
# attribute - A String representing the attribute that the Routes
|
|
64
|
+
# module should route this method under.
|
|
65
|
+
#
|
|
66
|
+
# Returns the result of pushing an object to class's attributes
|
|
67
|
+
# class variable.
|
|
29
68
|
def self.register_routable_attribute(method, attribute)
|
|
30
69
|
self.class_variable_get(:@@attributes) << {method: method, type: :attribute, attribute: attribute}
|
|
31
70
|
end
|
|
32
71
|
end
|
|
33
72
|
end
|
|
34
73
|
|
|
74
|
+
# Public: Gets the descendants for the Model class.
|
|
75
|
+
#
|
|
76
|
+
# Returns all of the descendants for the Model class.
|
|
35
77
|
def self.descendants
|
|
36
|
-
|
|
37
|
-
ObjectSpace.each_object(Class).select { |possibleChild| possibleChild < self }
|
|
78
|
+
ObjectSpace.each_object(Class).select { |possible_child| possible_child < self }
|
|
38
79
|
end
|
|
39
80
|
|
|
81
|
+
# Public: Converts this Model to its associated Controller.
|
|
82
|
+
#
|
|
83
|
+
# Returns the associated Controller if it exists, else nil.
|
|
40
84
|
def self.controller
|
|
41
85
|
(self.name.pluralize + "Controller").constantize
|
|
42
86
|
end
|
|
43
87
|
|
|
88
|
+
# Public: Validate that no invalid relations exist within this Model
|
|
44
89
|
def no_invalid_relations
|
|
45
90
|
# Get all of the belongs_to fields (ends with "_id" and not "_id" because that is the id).
|
|
46
|
-
attributes.keys.select
|
|
91
|
+
attributes.keys.select do |attribute|
|
|
92
|
+
attribute.end_with?("_id") && attribute != "_id"
|
|
93
|
+
end.each do |relation|
|
|
47
94
|
# Get the model for the belongs_to association.
|
|
48
95
|
model = "FReCon::".concat(relation.gsub(/_id\Z/, "").capitalize).constantize
|
|
49
|
-
errors.add(relation.to_sym, "is invalid") if relation_invalid(model, send(relation))
|
|
96
|
+
errors.add(relation.to_sym, "is invalid") if relation_invalid?(model, send(relation))
|
|
50
97
|
end
|
|
51
98
|
end
|
|
52
99
|
|
|
53
|
-
|
|
100
|
+
protected
|
|
101
|
+
|
|
102
|
+
# Internal: Determine if a relation is invalid.
|
|
103
|
+
#
|
|
104
|
+
# class_constant - The Model Class to test.
|
|
105
|
+
# id - The ID to check for extance.
|
|
106
|
+
#
|
|
107
|
+
# Returns true if the relation is invalid, false if not.
|
|
108
|
+
def relation_invalid?(class_constant, id)
|
|
54
109
|
class_constant.find_by(id: id).nil?
|
|
55
110
|
end
|
|
56
111
|
end
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
require "frecon/model"
|
|
11
11
|
|
|
12
12
|
module FReCon
|
|
13
|
+
# Public: The Competition model.
|
|
13
14
|
class Competition < Model
|
|
14
15
|
field :location, type: String
|
|
15
16
|
field :name, type: String
|
|
@@ -20,14 +21,17 @@ module FReCon
|
|
|
20
21
|
validates :location, :name, presence: true
|
|
21
22
|
validates :name, uniqueness: true
|
|
22
23
|
|
|
24
|
+
# Public: Get this Competition's Matches' Records
|
|
23
25
|
def records
|
|
24
26
|
Record.in match_id: matches.map(&:id)
|
|
25
27
|
end
|
|
26
28
|
|
|
29
|
+
# Public: Get this Competition's Participations' Robots
|
|
27
30
|
def robots
|
|
28
31
|
Robot.in id: participations.map(&:robot_id)
|
|
29
32
|
end
|
|
30
33
|
|
|
34
|
+
# Public: Get this Competition's Participations' Robots' Teams
|
|
31
35
|
def teams
|
|
32
36
|
Team.in id: robots.map(&:team_id)
|
|
33
37
|
end
|
data/lib/frecon/models/match.rb
CHANGED
|
@@ -11,6 +11,7 @@ require "frecon/model"
|
|
|
11
11
|
require "frecon/match_number"
|
|
12
12
|
|
|
13
13
|
module FReCon
|
|
14
|
+
# Public: The Match model.
|
|
14
15
|
class Match < Model
|
|
15
16
|
field :number, type: MatchNumber
|
|
16
17
|
|
|
@@ -22,14 +23,17 @@ module FReCon
|
|
|
22
23
|
|
|
23
24
|
validates :number, :competition_id, presence: true
|
|
24
25
|
|
|
26
|
+
# Public: Get this Match's Participations
|
|
25
27
|
def participations
|
|
26
28
|
Participation.in id: records.map(&:participation_id)
|
|
27
29
|
end
|
|
28
30
|
|
|
31
|
+
# Public: Get this Match's Participations' Robots
|
|
29
32
|
def robots
|
|
30
33
|
Robot.in id: participations.map(&:robot_id)
|
|
31
34
|
end
|
|
32
35
|
|
|
36
|
+
# Public: Get this Match's Participations' Robots' Teams
|
|
33
37
|
def teams
|
|
34
38
|
Team.in id: robots.map(&:team_id)
|
|
35
39
|
end
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
require "frecon/model"
|
|
11
11
|
|
|
12
12
|
module FReCon
|
|
13
|
+
# Public: The Participation model.
|
|
13
14
|
class Participation < Model
|
|
14
15
|
belongs_to :robot
|
|
15
16
|
belongs_to :competition
|
|
@@ -17,10 +18,12 @@ module FReCon
|
|
|
17
18
|
|
|
18
19
|
validates :robot_id, :competition_id, presence: true
|
|
19
20
|
|
|
21
|
+
# Public: Get this Participation's Robot's Team
|
|
20
22
|
def team
|
|
21
23
|
robot.team
|
|
22
24
|
end
|
|
23
25
|
|
|
26
|
+
# Public: Get this Participation's Competition's Matches
|
|
24
27
|
def matches
|
|
25
28
|
competition.matches
|
|
26
29
|
end
|
data/lib/frecon/models/record.rb
CHANGED
|
@@ -11,6 +11,7 @@ require "frecon/model"
|
|
|
11
11
|
require "frecon/position"
|
|
12
12
|
|
|
13
13
|
module FReCon
|
|
14
|
+
# Public: The Record model.
|
|
14
15
|
class Record < Model
|
|
15
16
|
field :notes, type: String
|
|
16
17
|
field :position, type: Position
|
|
@@ -20,14 +21,17 @@ module FReCon
|
|
|
20
21
|
|
|
21
22
|
validates :position, :match_id, :participation_id, presence: true
|
|
22
23
|
|
|
24
|
+
# Public: Get this Record's Match's Competition
|
|
23
25
|
def competition
|
|
24
26
|
match.competition
|
|
25
27
|
end
|
|
26
28
|
|
|
29
|
+
# Public: Get this Record's Participation's Robot
|
|
27
30
|
def robot
|
|
28
31
|
participation.robot
|
|
29
32
|
end
|
|
30
33
|
|
|
34
|
+
# Public: Get this Record's Participation's Robot's Team
|
|
31
35
|
def team
|
|
32
36
|
participation.robot.team
|
|
33
37
|
end
|
data/lib/frecon/models/robot.rb
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
require "frecon/model"
|
|
11
11
|
|
|
12
12
|
module FReCon
|
|
13
|
+
# Public: The Robot model.
|
|
13
14
|
class Robot < Model
|
|
14
15
|
# This is an optional field we included for organization.
|
|
15
16
|
field :name, type: String
|
|
@@ -19,14 +20,17 @@ module FReCon
|
|
|
19
20
|
|
|
20
21
|
validates :team_id, presence: true
|
|
21
22
|
|
|
23
|
+
# Public: Get this Robot's Participations' Competitions
|
|
22
24
|
def competitions
|
|
23
25
|
Competition.in id: participations.map(&:competition_id)
|
|
24
26
|
end
|
|
25
27
|
|
|
28
|
+
# Public: Get this Robot's Participations' Records
|
|
26
29
|
def records
|
|
27
30
|
Record.in participation_id: participations.map(&:id)
|
|
28
31
|
end
|
|
29
32
|
|
|
33
|
+
# Public: Get this Robot's Participations' Records' Matches
|
|
30
34
|
def matches
|
|
31
35
|
Match.in id: records.map(&:match_id).uniq
|
|
32
36
|
end
|
data/lib/frecon/models/team.rb
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
require "frecon/model"
|
|
11
11
|
|
|
12
12
|
module FReCon
|
|
13
|
+
# Public: The Team model.
|
|
13
14
|
class Team < Model
|
|
14
15
|
field :number, type: Integer
|
|
15
16
|
|
|
@@ -21,23 +22,31 @@ module FReCon
|
|
|
21
22
|
|
|
22
23
|
validates :number, presence: true, uniqueness: true, numericality: { greater_than: 0 }
|
|
23
24
|
|
|
25
|
+
# Public: Find a team by number.
|
|
26
|
+
#
|
|
27
|
+
# team_number - An Integer to be used to compare.
|
|
28
|
+
#
|
|
29
|
+
# Returns a Team if one exists with the given number, otherwise nil.
|
|
24
30
|
def self.number(team_number)
|
|
25
|
-
# Team.find_by number: team_number
|
|
26
31
|
find_by number: team_number
|
|
27
32
|
end
|
|
28
33
|
|
|
34
|
+
# Public: Get this Team's Robots' Participations
|
|
29
35
|
def participations
|
|
30
36
|
Participation.in robot_id: robots.map(&:id)
|
|
31
37
|
end
|
|
32
38
|
|
|
39
|
+
# Public: Get this Team's Robots' Participations' Competitions
|
|
33
40
|
def competitions
|
|
34
41
|
Competition.in id: participations.map(&:competition_id)
|
|
35
42
|
end
|
|
36
43
|
|
|
44
|
+
# Public: Get this Team's Robots' Participations' Records
|
|
37
45
|
def records
|
|
38
46
|
Record.in participation_id: participations.map(&:id)
|
|
39
47
|
end
|
|
40
48
|
|
|
49
|
+
# Public: Get this Team's Robots' Participations' Competitions' Matches
|
|
41
50
|
def matches
|
|
42
51
|
Match.in competition_id: competitions.map(&:id)
|
|
43
52
|
end
|
|
@@ -9,24 +9,63 @@
|
|
|
9
9
|
|
|
10
10
|
require "mongoid"
|
|
11
11
|
|
|
12
|
+
# Public: An extension for the Mongoid module.
|
|
12
13
|
module Mongoid
|
|
14
|
+
# Public: A monkey-patch for the Mongoid::Criteria class which introduces
|
|
15
|
+
# a #psv_filter method.
|
|
13
16
|
class Criteria
|
|
17
|
+
# Public: Filter by given PSV parameters.
|
|
18
|
+
#
|
|
19
|
+
# PSV is an introduced system that can be used within query strings to
|
|
20
|
+
# narrow a query. Since HTTP query strings can use "+" to act as spaces
|
|
21
|
+
# within a key-value pair, one can use these pluses to define nested
|
|
22
|
+
# query parameters when querying the database as in an indexing or
|
|
23
|
+
# showing request.
|
|
24
|
+
#
|
|
25
|
+
# psv_parameters - A Hash of PSV strings to comparison values.
|
|
26
|
+
#
|
|
27
|
+
# Examples
|
|
28
|
+
#
|
|
29
|
+
# Record.all.psv_filter({"participation robot team number" => "2503"})
|
|
30
|
+
# => #<Mongoid::Criteria ...>
|
|
31
|
+
#
|
|
32
|
+
# # Since each instance of Record has a :team shortcut method,
|
|
33
|
+
# # we can just filter it like so.
|
|
34
|
+
# Record.all.psv_filter({"team number" => "2503"})
|
|
35
|
+
# => #<Mongoid::Criteria ...>
|
|
36
|
+
#
|
|
37
|
+
# Returns a filtered version of self.
|
|
14
38
|
def psv_filter(psv_parameters = {})
|
|
15
39
|
collection = self
|
|
16
40
|
|
|
41
|
+
# Iterate through the Hash of query Strings to values, filtering using
|
|
42
|
+
# each pairing where the key is the query specifier and the value is the
|
|
43
|
+
# value that the last word in the query specifier is equal to. For
|
|
44
|
+
# multiple key-value pairs, just keep adding specifiers to the chain.
|
|
17
45
|
psv_parameters.each do |psv_string, comparison_value|
|
|
18
|
-
|
|
46
|
+
# Split the query String, and convert each subsequent String
|
|
47
|
+
# to a symbol. Then, reverse the array to make it easy to perform
|
|
48
|
+
# an inside-out operation.
|
|
49
|
+
psv_keys = psv_string.split(/\W/).map do |psv_key|
|
|
19
50
|
psv_key.to_sym
|
|
20
51
|
end.reverse
|
|
21
52
|
|
|
53
|
+
# Get the final key in the query string.
|
|
22
54
|
comparison_key = psv_keys.shift
|
|
23
55
|
|
|
56
|
+
# Create a comparison hash to be used to compare <attribute> to
|
|
57
|
+
# <expected value>.
|
|
24
58
|
if comparison_value.length == 0 || comparison_value == "__nil__"
|
|
25
59
|
comparison_hash = {comparison_key => nil}
|
|
26
60
|
else
|
|
27
61
|
comparison_hash = {comparison_key => comparison_value}
|
|
28
62
|
end
|
|
29
63
|
|
|
64
|
+
# Each of the subsequent keys should be a model name. Generate a string
|
|
65
|
+
# corresponding to the "<model>" + "_id" for use as the comparison key,
|
|
66
|
+
# and find the model class by generating a constant.
|
|
67
|
+
#
|
|
68
|
+
# Then, nest a comparison around the current comparison hash.
|
|
30
69
|
psv_keys.each do |model|
|
|
31
70
|
model_id = (model.to_s + '_id').to_sym
|
|
32
71
|
model_class = ("FReCon::" + model.to_s.capitalize).constantize
|
|
@@ -34,9 +73,11 @@ module Mongoid
|
|
|
34
73
|
comparison_hash = {model_id => model_class.in(comparison_hash).map(&:id)}
|
|
35
74
|
end
|
|
36
75
|
|
|
76
|
+
# Finally, complete this nested comparison.
|
|
37
77
|
collection = collection.in(comparison_hash)
|
|
38
78
|
end
|
|
39
79
|
|
|
80
|
+
# Return the fully-filtered collection.
|
|
40
81
|
collection
|
|
41
82
|
end
|
|
42
83
|
end
|
data/lib/frecon/position.rb
CHANGED
|
@@ -10,20 +10,47 @@
|
|
|
10
10
|
require "frecon/base"
|
|
11
11
|
|
|
12
12
|
module FReCon
|
|
13
|
+
# Public: A wrapper to handle converting team positions and storing them.
|
|
13
14
|
class Position
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
#
|
|
15
|
+
# Public: The alliance part of the position
|
|
16
|
+
#
|
|
17
|
+
# Examples
|
|
18
|
+
#
|
|
19
|
+
# position = Position.new('r2')
|
|
20
|
+
# position.alliance
|
|
21
|
+
# # => :red
|
|
22
|
+
attr_reader :alliance
|
|
23
|
+
|
|
24
|
+
# Public: The slot part of the position.
|
|
25
|
+
#
|
|
26
|
+
# Examples
|
|
27
|
+
#
|
|
28
|
+
# position = Position.new('r2')
|
|
29
|
+
# position.number
|
|
30
|
+
# # => 2
|
|
31
|
+
attr_reader :number
|
|
32
|
+
|
|
33
|
+
# Public: Convert a stored position to a Position object.
|
|
34
|
+
#
|
|
35
|
+
# object - String representation of a position (mongoized)
|
|
36
|
+
#
|
|
37
|
+
# Returns Position parsed from object.
|
|
17
38
|
def self.demongoize(object)
|
|
18
|
-
# `object' should *always* be a
|
|
39
|
+
# `object' should *always* be a String (since MatchNumber#mongoize returns a
|
|
19
40
|
# String which is what is stored in the database)
|
|
20
41
|
raise ArgumentError, "`object' must be a String" unless object.is_a?(String)
|
|
21
42
|
|
|
22
43
|
Position.new(object)
|
|
23
44
|
end
|
|
24
45
|
|
|
25
|
-
#
|
|
26
|
-
#
|
|
46
|
+
# Public: Convert a Position object to a storable string representation.
|
|
47
|
+
#
|
|
48
|
+
# object - A Position, String, or Hash. If Position, run #mongoize on it.
|
|
49
|
+
# If String, create a new Position object for it, then run
|
|
50
|
+
# #mongoize on it. If Hash, convert its keys to symbols, then
|
|
51
|
+
# pull out the :alliance and :number keys to generate a Position.
|
|
52
|
+
#
|
|
53
|
+
# Returns String containing the mongo-ready value for the representation.
|
|
27
54
|
def self.mongoize(object)
|
|
28
55
|
case object
|
|
29
56
|
when Position
|
|
@@ -39,7 +66,15 @@ module FReCon
|
|
|
39
66
|
end
|
|
40
67
|
end
|
|
41
68
|
|
|
42
|
-
#
|
|
69
|
+
# Public: Convert a Position object to a storable string representation for
|
|
70
|
+
# queries.
|
|
71
|
+
#
|
|
72
|
+
# object - A Position, String, or Hash. If Position, run #mongoize on it.
|
|
73
|
+
# If String, create a new Position object for it, then run
|
|
74
|
+
# #mongoize on it. If Hash, convert its keys to symbols, then
|
|
75
|
+
# pull out the :alliance and :number keys to generate a Position.
|
|
76
|
+
#
|
|
77
|
+
# Returns String containing the mongo-ready value for the representation.
|
|
43
78
|
def self.evolve(object)
|
|
44
79
|
case object
|
|
45
80
|
when Position
|
|
@@ -55,6 +90,9 @@ module FReCon
|
|
|
55
90
|
end
|
|
56
91
|
end
|
|
57
92
|
|
|
93
|
+
# Public: Convert to a storable string representation.
|
|
94
|
+
#
|
|
95
|
+
# Returns String representing the Position's data.
|
|
58
96
|
def mongoize
|
|
59
97
|
to_s
|
|
60
98
|
end
|
|
@@ -112,14 +150,19 @@ module FReCon
|
|
|
112
150
|
end
|
|
113
151
|
end
|
|
114
152
|
|
|
153
|
+
# Public: Convert to a String.
|
|
154
|
+
#
|
|
155
|
+
# Returns String representing the position data.
|
|
115
156
|
def to_s
|
|
116
157
|
"#{@alliance[0]}#{@number}"
|
|
117
158
|
end
|
|
118
159
|
|
|
160
|
+
# Public: Determine if Position is on blue alliance.
|
|
119
161
|
def is_blue?
|
|
120
162
|
@alliance == :blue
|
|
121
163
|
end
|
|
122
164
|
|
|
165
|
+
# Public: Determine if Position is on red alliance.
|
|
123
166
|
def is_red?
|
|
124
167
|
@alliance == :red
|
|
125
168
|
end
|
data/lib/frecon/request_error.rb
CHANGED
|
@@ -9,9 +9,17 @@
|
|
|
9
9
|
|
|
10
10
|
require "json"
|
|
11
11
|
|
|
12
|
+
# Public: A class representing errors that emanate from request handling.
|
|
12
13
|
class RequestError < StandardError
|
|
14
|
+
# Public: The Array or Integer representing what can be returned from the
|
|
15
|
+
# request handler.
|
|
13
16
|
attr_reader :return_value
|
|
14
17
|
|
|
18
|
+
# Public: Initialize a RequestError.
|
|
19
|
+
#
|
|
20
|
+
# code - An Integer representing the HTTP status code.
|
|
21
|
+
# message - A String representing the error message.
|
|
22
|
+
# context - An Object containing any necessary debugging values.
|
|
15
23
|
def initialize(code, message = nil, context = nil)
|
|
16
24
|
@code = code
|
|
17
25
|
@message = message
|
data/lib/frecon/routes.rb
CHANGED
|
@@ -10,7 +10,13 @@
|
|
|
10
10
|
require "frecon/controllers"
|
|
11
11
|
|
|
12
12
|
module FReCon
|
|
13
|
+
# Public: A module containing all of the routes.
|
|
13
14
|
module Routes
|
|
15
|
+
# Public: Set up basic resource route handlers.
|
|
16
|
+
#
|
|
17
|
+
# base - Sinatra::Application to register the routes under.
|
|
18
|
+
# name - String containing the model name.
|
|
19
|
+
# controller - Controller-like object that contains key methods.
|
|
14
20
|
def self.resource_routes(base, name, controller)
|
|
15
21
|
base.post "/#{name}" do
|
|
16
22
|
begin
|
|
@@ -53,6 +59,11 @@ module FReCon
|
|
|
53
59
|
end
|
|
54
60
|
end
|
|
55
61
|
|
|
62
|
+
# Public: Set up basic attribute route handlers.
|
|
63
|
+
#
|
|
64
|
+
# base - Sinatra::Application to register the routes under.
|
|
65
|
+
# name - String containing the model name.
|
|
66
|
+
# controller - Controller-like object.
|
|
56
67
|
def self.attribute_routes(base, name, controller)
|
|
57
68
|
model = controller.model
|
|
58
69
|
|
|
@@ -82,6 +93,9 @@ module FReCon
|
|
|
82
93
|
end
|
|
83
94
|
end
|
|
84
95
|
|
|
96
|
+
# Public: Bootstrap the routes into inclusors of this module.
|
|
97
|
+
#
|
|
98
|
+
# base - The child that included this module (should be a Sinatra App)
|
|
85
99
|
def self.included(base)
|
|
86
100
|
resource_routes base, "teams", TeamsController
|
|
87
101
|
resource_routes base, "competitions", CompetitionsController
|
data/lib/frecon/server.rb
CHANGED
|
@@ -16,6 +16,7 @@ require "frecon/routes"
|
|
|
16
16
|
require "frecon/controllers"
|
|
17
17
|
|
|
18
18
|
module FReCon
|
|
19
|
+
# Public: The Sinatra web server.
|
|
19
20
|
class Server < Sinatra::Base
|
|
20
21
|
include Routes
|
|
21
22
|
|
|
@@ -23,23 +24,45 @@ module FReCon
|
|
|
23
24
|
content_type "application/json"
|
|
24
25
|
end
|
|
25
26
|
|
|
27
|
+
# Public: Start the Server.
|
|
28
|
+
#
|
|
29
|
+
# keyword_arguments - The Hash of arguments to use.
|
|
30
|
+
# :configuration - The Configuration to use when
|
|
31
|
+
# setting up the server.
|
|
32
|
+
#
|
|
33
|
+
# Returns the result of starting the server.
|
|
26
34
|
def self.start(**keyword_arguments)
|
|
27
35
|
run!(**keyword_arguments)
|
|
28
36
|
end
|
|
29
37
|
|
|
30
38
|
protected
|
|
31
39
|
|
|
40
|
+
# Internal: Set up the server.
|
|
41
|
+
#
|
|
42
|
+
# Sets the various Thin and Sinatra options, and sets up the database.
|
|
43
|
+
#
|
|
44
|
+
# :configuration - The Configuration to use when starting the server.
|
|
45
|
+
#
|
|
46
|
+
# Returns the result of setting up the database.
|
|
32
47
|
def self.setup!(configuration: Configuration.construct!)
|
|
48
|
+
# Set the Thin and Sinatra options.
|
|
33
49
|
set :server, %w[thin HTTP webrick]
|
|
34
50
|
set :bind, configuration["frecon"]["server"]["host"]
|
|
35
51
|
set :port, configuration["frecon"]["server"]["port"]
|
|
36
52
|
set :environment, configuration["frecon"]["server"]["environment"]
|
|
37
53
|
|
|
54
|
+
# Grab out the mongoid configuration.
|
|
38
55
|
mongoid = configuration["frecon"]["database"]["mongoid"]
|
|
39
56
|
|
|
40
|
-
|
|
57
|
+
# Set up the database.
|
|
58
|
+
Database.setup(environment, mongoid)
|
|
41
59
|
end
|
|
42
60
|
|
|
61
|
+
# Internal: Set up the server and start it.
|
|
62
|
+
#
|
|
63
|
+
# keyword_arguments - The Hash of arguments to use.
|
|
64
|
+
# :configuration - The Configuration to use when
|
|
65
|
+
# setting up the server.
|
|
43
66
|
def self.run!(**keyword_arguments)
|
|
44
67
|
setup!(**keyword_arguments)
|
|
45
68
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: frecon
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.5.
|
|
4
|
+
version: 0.5.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sam Craig
|
|
@@ -71,6 +71,48 @@ dependencies:
|
|
|
71
71
|
- - "~>"
|
|
72
72
|
- !ruby/object:Gem::Version
|
|
73
73
|
version: '0.13'
|
|
74
|
+
- !ruby/object:Gem::Dependency
|
|
75
|
+
name: yard
|
|
76
|
+
requirement: !ruby/object:Gem::Requirement
|
|
77
|
+
requirements:
|
|
78
|
+
- - "~>"
|
|
79
|
+
- !ruby/object:Gem::Version
|
|
80
|
+
version: '0.8'
|
|
81
|
+
type: :development
|
|
82
|
+
prerelease: false
|
|
83
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
84
|
+
requirements:
|
|
85
|
+
- - "~>"
|
|
86
|
+
- !ruby/object:Gem::Version
|
|
87
|
+
version: '0.8'
|
|
88
|
+
- !ruby/object:Gem::Dependency
|
|
89
|
+
name: yard-tomdoc
|
|
90
|
+
requirement: !ruby/object:Gem::Requirement
|
|
91
|
+
requirements:
|
|
92
|
+
- - "~>"
|
|
93
|
+
- !ruby/object:Gem::Version
|
|
94
|
+
version: '0.7'
|
|
95
|
+
type: :development
|
|
96
|
+
prerelease: false
|
|
97
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
98
|
+
requirements:
|
|
99
|
+
- - "~>"
|
|
100
|
+
- !ruby/object:Gem::Version
|
|
101
|
+
version: '0.7'
|
|
102
|
+
- !ruby/object:Gem::Dependency
|
|
103
|
+
name: yard-mongoid
|
|
104
|
+
requirement: !ruby/object:Gem::Requirement
|
|
105
|
+
requirements:
|
|
106
|
+
- - "~>"
|
|
107
|
+
- !ruby/object:Gem::Version
|
|
108
|
+
version: '0.0'
|
|
109
|
+
type: :development
|
|
110
|
+
prerelease: false
|
|
111
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
112
|
+
requirements:
|
|
113
|
+
- - "~>"
|
|
114
|
+
- !ruby/object:Gem::Version
|
|
115
|
+
version: '0.0'
|
|
74
116
|
description: A JSON API for scouting FRC competitions that manages the database for
|
|
75
117
|
the user.
|
|
76
118
|
email: frc-frecon@googlegroups.com
|
|
@@ -79,6 +121,8 @@ executables:
|
|
|
79
121
|
extensions: []
|
|
80
122
|
extra_rdoc_files: []
|
|
81
123
|
files:
|
|
124
|
+
- Gemfile
|
|
125
|
+
- Rakefile
|
|
82
126
|
- bin/frecon
|
|
83
127
|
- config/default.yml
|
|
84
128
|
- lib/frecon.rb
|