apiway 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/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +1 -0
- data/Rakefile +0 -0
- data/bin/apiway +13 -0
- data/lib/apiway/application.rb +53 -0
- data/lib/apiway/client.rb +171 -0
- data/lib/apiway/commands.rb +62 -0
- data/lib/apiway/controller.rb +124 -0
- data/lib/apiway/diff.rb +84 -0
- data/lib/apiway/errors.rb +62 -0
- data/lib/apiway/events.rb +23 -0
- data/lib/apiway/extensions.rb +29 -0
- data/lib/apiway/generator.rb +111 -0
- data/lib/apiway/logger.rb +41 -0
- data/lib/apiway/model.rb +58 -0
- data/lib/apiway/path.rb +7 -0
- data/lib/apiway/resource.rb +110 -0
- data/lib/apiway/version.rb +5 -0
- data/lib/apiway.rb +17 -0
- data/lib/generator/application/.gitignore +1 -0
- data/lib/generator/application/Gemfile +9 -0
- data/lib/generator/application/Procfile +1 -0
- data/lib/generator/application/README.md +0 -0
- data/lib/generator/application/Rakefile +3 -0
- data/lib/generator/application/app/base/.keep +0 -0
- data/lib/generator/application/app/base/base.rb +5 -0
- data/lib/generator/application/app/base/client.rb +21 -0
- data/lib/generator/application/app/base/routes.rb +11 -0
- data/lib/generator/application/app/controllers/.keep +0 -0
- data/lib/generator/application/app/controllers/application.rb +5 -0
- data/lib/generator/application/app/models/.keep +0 -0
- data/lib/generator/application/app/resources/.keep +0 -0
- data/lib/generator/application/app/resources/application.rb +5 -0
- data/lib/generator/application/config/application.rb +13 -0
- data/lib/generator/application/config/database.yml +17 -0
- data/lib/generator/application/config/environments/development.rb +9 -0
- data/lib/generator/application/config/environments/production.rb +9 -0
- data/lib/generator/application/config/environments/test.rb +10 -0
- data/lib/generator/application/config.ru +3 -0
- data/lib/generator/application/db/migrate/.keep +0 -0
- data/lib/generator/application/lib/.keep +0 -0
- data/lib/generator/application/public/.keep +0 -0
- data/lib/generator/templates/controller.tpl +22 -0
- data/lib/generator/templates/model.tpl +5 -0
- data/lib/generator/templates/resource.tpl +29 -0
- metadata +174 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e359eb647d0797382fe8d4960a74390d9e453527
|
4
|
+
data.tar.gz: a9bb742d1d44c02040161ed4332efe8cb5b425c1
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 87bbe8b23efea6c9d3b9d97c41771e26331e139bcfe2bd122babd82481373093111deafdf7382da9f31c626d24617695c2f5877b170f3412ad1052056ae27145
|
7
|
+
data.tar.gz: 2375c4599a6acbcbd3434fc205692cb2362582fd1afa6e71bae644d3b71ae93b7de2a0e11c0bc67435e6428fd5c0d0a99f5a0580eac67efcdab66ea614dd4ff0
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 4urbanoff
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
## Apiway
|
data/Rakefile
ADDED
File without changes
|
data/bin/apiway
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'erb'
|
4
|
+
require 'fileutils'
|
5
|
+
require 'logger'
|
6
|
+
require 'apiway/path'
|
7
|
+
require 'apiway/logger'
|
8
|
+
require 'apiway/version'
|
9
|
+
require 'apiway/extensions'
|
10
|
+
require 'apiway/generator'
|
11
|
+
require 'apiway/commands'
|
12
|
+
|
13
|
+
Apiway::Commands.run *ARGV
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Apiway
|
2
|
+
|
3
|
+
class Application < Sinatra::Base
|
4
|
+
|
5
|
+
|
6
|
+
set root: File.expand_path( '.' )
|
7
|
+
set static: true
|
8
|
+
set apiway_log: true
|
9
|
+
set active_record_log: true
|
10
|
+
set log_level: :debug
|
11
|
+
set database_file: File.join( root, 'config/database.yml' )
|
12
|
+
|
13
|
+
|
14
|
+
register Sinatra::ActiveRecordExtension
|
15
|
+
|
16
|
+
|
17
|
+
configure :development do
|
18
|
+
register Sinatra::Reloader
|
19
|
+
also_reload File.join( root, '**/*.rb' )
|
20
|
+
# also_reload File.join( Apiway.path, '**/*.rb' )
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
get '*' do
|
25
|
+
request.websocket? ? request.websocket{ |ws| Apiway::Client.new ws } : pass
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
%W(
|
30
|
+
lib/**/*.rb
|
31
|
+
config/environments/#{ environment.to_s }.rb
|
32
|
+
config/initializers/**/*.rb
|
33
|
+
app/base/**/*.rb
|
34
|
+
app/controllers/application.rb
|
35
|
+
app/resources/application.rb
|
36
|
+
app/**/*.rb
|
37
|
+
)
|
38
|
+
.map{ |path| Dir[ File.join( root, path ) ] }
|
39
|
+
.flatten.uniq.each{ |path| require path }
|
40
|
+
|
41
|
+
|
42
|
+
LoggerBase::apiway_log_level apiway_log
|
43
|
+
LoggerBase::activerecord_log_level activerecord_log
|
44
|
+
|
45
|
+
|
46
|
+
def self.tasks
|
47
|
+
require 'sinatra/activerecord/rake'
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
@@ -0,0 +1,171 @@
|
|
1
|
+
module Apiway
|
2
|
+
|
3
|
+
class Client
|
4
|
+
|
5
|
+
|
6
|
+
HANDLERS = Hash[
|
7
|
+
API::ALIVE, :alive,
|
8
|
+
API::QUERY, :run_controller,
|
9
|
+
RESOURCE::SYNC, :sync_resource,
|
10
|
+
RESOURCE::DESTROY, :destroy_resource
|
11
|
+
]
|
12
|
+
|
13
|
+
|
14
|
+
class << self
|
15
|
+
|
16
|
+
def all
|
17
|
+
@@all ||= []
|
18
|
+
@@all.each { |client| yield client } if block_given?
|
19
|
+
@@all
|
20
|
+
end
|
21
|
+
|
22
|
+
def sync_changes( changed_models )
|
23
|
+
all { |client| client.sync_changes changed_models }
|
24
|
+
end
|
25
|
+
|
26
|
+
def on_connected( &block )
|
27
|
+
block_given? ? @@on_connected = block : @@on_connected ||= Proc.new {}
|
28
|
+
end
|
29
|
+
|
30
|
+
def on_message( &block )
|
31
|
+
block_given? ? @@on_message = block : @@on_message ||= Proc.new {}
|
32
|
+
end
|
33
|
+
|
34
|
+
def on_disconnected( &block )
|
35
|
+
block_given? ? @@on_disconnected = block : @@on_disconnected ||= Proc.new {}
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
def initialize( ws )
|
42
|
+
@ws = ws
|
43
|
+
@ws.onopen { on_connected }
|
44
|
+
@ws.onmessage { |msg| on_message msg }
|
45
|
+
@ws.onclose { on_disconnected }
|
46
|
+
@storage = {}
|
47
|
+
@resources = {}
|
48
|
+
end
|
49
|
+
|
50
|
+
def []( name = nil )
|
51
|
+
@storage[ name ]
|
52
|
+
end
|
53
|
+
|
54
|
+
def []=( name, value )
|
55
|
+
@storage[ name ] = value
|
56
|
+
Thread.current[ :changed_models ].concat Apiway::Model.all
|
57
|
+
value
|
58
|
+
end
|
59
|
+
|
60
|
+
def sync_changes( changed_models )
|
61
|
+
@resources.values.each { |resource| resource.sync_changes changed_models }
|
62
|
+
end
|
63
|
+
|
64
|
+
def trigger( *args )
|
65
|
+
send_event API::TRIGGER, args: args
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def processing
|
72
|
+
begin
|
73
|
+
Thread.new {
|
74
|
+
Thread.current[ :changed_models ] = []
|
75
|
+
Thread.current[ :methods_to_call ] = []
|
76
|
+
yield
|
77
|
+
self.class.sync_changes Thread.current[ :changed_models ].uniq
|
78
|
+
call_methods Thread.current[ :methods_to_call ]
|
79
|
+
}.join
|
80
|
+
rescue Exception => e
|
81
|
+
Log.error "#{ e.message }\n#{ e.backtrace.join "\n" }"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def on_connected
|
86
|
+
processing do
|
87
|
+
self.class.all << self
|
88
|
+
instance_eval &self.class.on_connected
|
89
|
+
end
|
90
|
+
Log.info "Client connected"
|
91
|
+
end
|
92
|
+
|
93
|
+
def on_message( msg )
|
94
|
+
@msg = parseMessage( msg ) rescue { event: API::ALIVE, data: nil }
|
95
|
+
Log.debug "New message: \n#{ JSON.pretty_generate( @msg ) }" if Log.debug?
|
96
|
+
processing do
|
97
|
+
instance_exec @msg, &self.class.on_message
|
98
|
+
handler = HANDLERS[ @msg[ :event ] ] or raise EventHandlerNotExists, @msg[ :event ]
|
99
|
+
send handler, @msg[ :data ]
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def on_disconnected
|
104
|
+
processing do
|
105
|
+
self.class.all.delete self
|
106
|
+
instance_eval &self.class.on_disconnected
|
107
|
+
end
|
108
|
+
Log.info "Client disconnected"
|
109
|
+
end
|
110
|
+
|
111
|
+
def parseMessage( msg )
|
112
|
+
msg = JSON.parse msg, quirks_mode: true
|
113
|
+
msg.keys_to_sym!
|
114
|
+
end
|
115
|
+
|
116
|
+
def send_json( msg )
|
117
|
+
@ws.send JSON.generate( msg, quirks_mode: true )
|
118
|
+
Log.debug "Send message: \n#{ JSON.pretty_generate( msg ) }" if Log.debug?
|
119
|
+
end
|
120
|
+
|
121
|
+
def send_event( event, data = nil )
|
122
|
+
send_json event: event, data: data
|
123
|
+
end
|
124
|
+
|
125
|
+
def success( result )
|
126
|
+
send_event API::SUCCESS, result: result, query_id: @msg[ :data ][ :query_id ]
|
127
|
+
end
|
128
|
+
|
129
|
+
def failure( result )
|
130
|
+
send_event API::FAILURE, result: result, query_id: @msg[ :data ][ :query_id ]
|
131
|
+
end
|
132
|
+
|
133
|
+
def call_methods( methods )
|
134
|
+
methods.each { |method, args| send method, *args }
|
135
|
+
end
|
136
|
+
|
137
|
+
def alive( data )
|
138
|
+
send_event API::ALIVE
|
139
|
+
end
|
140
|
+
|
141
|
+
def run_controller( data )
|
142
|
+
name, action, params = data.values_at :name, :action, :params
|
143
|
+
name = "#{ name }Controller"
|
144
|
+
begin
|
145
|
+
controller = Object.const_get( name ).new action.to_sym, self, params
|
146
|
+
rescue NameError
|
147
|
+
raise ControllerNotExists, name
|
148
|
+
else
|
149
|
+
controller.run
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def sync_resource( data )
|
154
|
+
id, name, params = data.values_at :id, :name, :params
|
155
|
+
name = "#{ name }Resource"
|
156
|
+
begin
|
157
|
+
@resources[ id ] ||= Object.const_get( name ).new id, self
|
158
|
+
rescue
|
159
|
+
raise ResourceNotExists, name
|
160
|
+
else
|
161
|
+
@resources[ id ].set_params( params ).sync
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def destroy_resource( data )
|
166
|
+
@resources.delete data[ :id ]
|
167
|
+
end
|
168
|
+
|
169
|
+
end
|
170
|
+
|
171
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Apiway
|
2
|
+
|
3
|
+
module Commands
|
4
|
+
|
5
|
+
|
6
|
+
class << self
|
7
|
+
|
8
|
+
HANDLERS = {
|
9
|
+
version: [ '-v', 'v', 'version' ],
|
10
|
+
server: [ '-s', 's', 'server' ],
|
11
|
+
generate: [ '-g', 'g', 'generate' ],
|
12
|
+
create: [ '-n', 'n', 'new' ],
|
13
|
+
help: [ '-h', 'h', 'help' ]
|
14
|
+
}
|
15
|
+
|
16
|
+
DESC = {
|
17
|
+
version: 'Show gem version',
|
18
|
+
server: 'Launch thin server, alias for `bundle exec thin start`',
|
19
|
+
generate: 'Launch generator, run `apiway generator help` to show commands of generator',
|
20
|
+
create: 'Creating a new application',
|
21
|
+
help: 'Show list of commands'
|
22
|
+
}
|
23
|
+
|
24
|
+
|
25
|
+
def run( command = nil, *args )
|
26
|
+
return help unless command
|
27
|
+
HANDLERS.each { |handler, commands| return send( handler, *args ) if commands.include? command }
|
28
|
+
puts "Apiway: Unknown command `#{ args.unshift( command ).join " " }`"
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def version( *args )
|
35
|
+
puts "Apiway version #{ Apiway::VERSION }"
|
36
|
+
end
|
37
|
+
|
38
|
+
def server( *args )
|
39
|
+
exec "bundle exec thin start #{ args.join " " }"
|
40
|
+
end
|
41
|
+
|
42
|
+
def generate( *args )
|
43
|
+
Generator.run *args
|
44
|
+
end
|
45
|
+
|
46
|
+
def create( *args )
|
47
|
+
generate "app", *args
|
48
|
+
end
|
49
|
+
|
50
|
+
def help( *args )
|
51
|
+
puts "\n Apiway commands: \n\n"
|
52
|
+
HANDLERS.each do |handler, commands|
|
53
|
+
puts " [#{ commands.join( "], [" ) }]".ljust(30) << "# #{ DESC[ handler ] } "
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
module Apiway
|
2
|
+
|
3
|
+
module Controller
|
4
|
+
|
5
|
+
|
6
|
+
|
7
|
+
class << self
|
8
|
+
|
9
|
+
def included( base )
|
10
|
+
base.class_eval do
|
11
|
+
extend ClassMethods
|
12
|
+
include InstanceMethods
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
module ClassMethods
|
21
|
+
|
22
|
+
def action( name, &block )
|
23
|
+
block_given? ? actions[ name ] = block : actions[ name ] or raise ControllerActionNotExists.new( self.name, name )
|
24
|
+
end
|
25
|
+
|
26
|
+
def before_action( method_name, only: [], except: [] )
|
27
|
+
register_filter :before, method_name, only, except
|
28
|
+
end
|
29
|
+
|
30
|
+
def after_action( method_name, only: [], except: [] )
|
31
|
+
register_filter :after, method_name, only, except
|
32
|
+
end
|
33
|
+
|
34
|
+
def select_filters( type, action_name )
|
35
|
+
filters( type ).select do |method_name, only, except|
|
36
|
+
( only.empty? || only.include?( action_name ) ) && ( except.empty? || !except.include?( action_name ) )
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def actions
|
44
|
+
@actions ||= {}
|
45
|
+
end
|
46
|
+
|
47
|
+
def filters( type )
|
48
|
+
( @filters ||= {} )[ type ] ||= []
|
49
|
+
end
|
50
|
+
|
51
|
+
def register_filter( type, method_name, only, except )
|
52
|
+
only = [].push( only ).flatten
|
53
|
+
except = [].push( except ).flatten
|
54
|
+
filters( type ) << [ method_name, only, except ]
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
|
61
|
+
module InstanceMethods
|
62
|
+
|
63
|
+
def initialize( action_name, client, params = {} )
|
64
|
+
@action_name = action_name
|
65
|
+
@action = self.class.action @action_name
|
66
|
+
@client = client
|
67
|
+
@params = params
|
68
|
+
end
|
69
|
+
|
70
|
+
def run
|
71
|
+
begin
|
72
|
+
run_filters :before
|
73
|
+
result = run_action
|
74
|
+
run_filters :after
|
75
|
+
rescue ControllerError => e
|
76
|
+
failure e.params
|
77
|
+
else
|
78
|
+
success result
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
protected
|
84
|
+
|
85
|
+
attr_reader :client, :params
|
86
|
+
|
87
|
+
def trigger( *args )
|
88
|
+
add_method_to_call :trigger, args
|
89
|
+
end
|
90
|
+
|
91
|
+
def error( params )
|
92
|
+
raise ControllerError, params
|
93
|
+
end
|
94
|
+
|
95
|
+
|
96
|
+
private
|
97
|
+
|
98
|
+
def run_action
|
99
|
+
instance_eval &@action
|
100
|
+
end
|
101
|
+
|
102
|
+
def run_filters( type )
|
103
|
+
self.class.select_filters( type, @action_name ).each { |method_name, only, except| send method_name }
|
104
|
+
end
|
105
|
+
|
106
|
+
def add_method_to_call( method, args )
|
107
|
+
Thread.current[ :methods_to_call ] << [ method, args ]
|
108
|
+
end
|
109
|
+
|
110
|
+
def success( *args )
|
111
|
+
add_method_to_call :success, args
|
112
|
+
end
|
113
|
+
|
114
|
+
def failure( *args )
|
115
|
+
add_method_to_call :failure, args
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
|
120
|
+
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
data/lib/apiway/diff.rb
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
module Apiway
|
2
|
+
|
3
|
+
class Diff
|
4
|
+
|
5
|
+
|
6
|
+
def initialize( source, target )
|
7
|
+
@del, @add, @del_c, @add_c = {}, {}, 0, 0
|
8
|
+
calculate source.to_s, target.to_s
|
9
|
+
end
|
10
|
+
|
11
|
+
def patch
|
12
|
+
[ @del, @add ]
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def calculate( source, target )
|
19
|
+
|
20
|
+
if found = find_middle( source, target )
|
21
|
+
|
22
|
+
source_l, target_l, source, source_r, target_r = found
|
23
|
+
calculate source_l, target_l
|
24
|
+
@del_c += source.size
|
25
|
+
@add_c += source.size
|
26
|
+
calculate source_r, target_r
|
27
|
+
|
28
|
+
else
|
29
|
+
|
30
|
+
unless source.empty?
|
31
|
+
@del[ @del_c ] = source.size
|
32
|
+
end
|
33
|
+
|
34
|
+
unless target.empty?
|
35
|
+
@add[ @add_c ] = target
|
36
|
+
@add_c += target.size
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
def find_middle( source, target, min = 0, max = nil )
|
44
|
+
|
45
|
+
return nil if source.empty? || target.empty?
|
46
|
+
|
47
|
+
max = source.size unless max
|
48
|
+
size = min + ( ( max - min ) / 2.to_f ).round
|
49
|
+
|
50
|
+
subsets_each( source, size ) do |subset, first, last|
|
51
|
+
|
52
|
+
if found = target.index( subset )
|
53
|
+
|
54
|
+
return (
|
55
|
+
size != min && find_middle( source, target, size, max ) ||
|
56
|
+
(
|
57
|
+
source_l = source[ 0...first ]
|
58
|
+
target_l = target[ 0...found ]
|
59
|
+
source_r = source[ last...source.size ]
|
60
|
+
target_r = target[ found + subset.size...target.size ]
|
61
|
+
[ source_l, target_l, subset, source_r, target_r ]
|
62
|
+
)
|
63
|
+
)
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
size != max && find_middle( source, target, min, size ) || nil
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
def subsets_each( source, size )
|
74
|
+
( source.size - size + 1 ).times do |first|
|
75
|
+
last = first + size
|
76
|
+
subset = source[ first...last ]
|
77
|
+
yield subset, first, last
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Apiway
|
2
|
+
|
3
|
+
|
4
|
+
class EventHandlerNotExists < StandardError
|
5
|
+
|
6
|
+
def initialize( name )
|
7
|
+
super "Event handler \"#{ name }\" not exists"
|
8
|
+
end
|
9
|
+
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
class ControllerNotExists < StandardError
|
14
|
+
|
15
|
+
def initialize( name )
|
16
|
+
super "\"#{ name }\" not exists"
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
class ControllerActionNotExists < StandardError
|
23
|
+
|
24
|
+
def initialize( controller_name, action_name )
|
25
|
+
super "Action \"#{ action_name }\" not exists in \"#{ controller_name }\""
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
class ResourceNotExists < StandardError
|
32
|
+
|
33
|
+
def initialize( name )
|
34
|
+
super "\"#{ name }\" not exists"
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
class ResourceError < StandardError
|
41
|
+
|
42
|
+
attr_reader :params
|
43
|
+
|
44
|
+
def initialize( params = nil )
|
45
|
+
@params = params
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
class ControllerError < StandardError
|
52
|
+
|
53
|
+
attr_reader :params
|
54
|
+
|
55
|
+
def initialize( params = nil )
|
56
|
+
@params = params
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class Hash
|
2
|
+
|
3
|
+
def keys_to_sym!
|
4
|
+
self.keys.each do |key|
|
5
|
+
self[ key ].keys_to_sym! if self[ key ].is_a? Hash
|
6
|
+
self[ ( key.to_sym rescue key ) ] = self.delete key
|
7
|
+
end
|
8
|
+
self
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
class String
|
15
|
+
|
16
|
+
def underscore!
|
17
|
+
gsub!( /(.)([A-Z])/, '\1_\2' )
|
18
|
+
downcase!
|
19
|
+
end
|
20
|
+
|
21
|
+
def underscore
|
22
|
+
dup.tap { |s| s.underscore! }
|
23
|
+
end
|
24
|
+
|
25
|
+
def camelize
|
26
|
+
self.split( '_' ).collect( &:capitalize ).join
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|