ruby_ext_direct 0.0.2 → 0.0.3
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.
- data/Gemfile +1 -1
- data/README.markdown +60 -0
- data/lib/ext_direct/api.rb +68 -10
- data/lib/ext_direct/router.rb +25 -5
- data/lib/ext_direct/version.rb +1 -1
- data/ruby_ext_direct.gemspec +1 -0
- data/test/test_ext_direct.rb +19 -0
- metadata +17 -34
- data/README +0 -12
- data/examples/API/Gemfile +0 -29
- data/examples/API/app/actions/api_action.rb +0 -18
- data/examples/API/app/actions/home_action.rb +0 -11
- data/examples/API/app/actions/router_action.rb +0 -18
- data/examples/API/application.rb +0 -37
- data/examples/API/config.ru +0 -25
- data/examples/API/config/database.yml +0 -6
- data/examples/API/config/routes.rb +0 -6
- data/examples/API/public/NamesApp/app/store/NamesStore.js +0 -48
- data/examples/API/public/NamesApp/app/view/namesWindow.js +0 -21
- data/examples/API/public/NamesApp/app/view/ui/namesWindow.js +0 -58
- data/examples/API/public/NamesApp/designer.html +0 -19
- data/examples/API/public/NamesApp/designer.js +0 -32
- data/examples/API/public/NamesApp/designer_includeOrder.txt +0 -3
- data/examples/API/public/namesApp.xds +0 -200
- data/examples/rack/config.ru +0 -40
- data/examples/rack/exposed_classes/countries.rb +0 -10
- data/examples/rack/exposed_classes/names.rb +0 -82
- data/examples/rack/html/NamesApp/app/store/NamesStore.js +0 -56
- data/examples/rack/html/NamesApp/app/view/namesWindow.js +0 -49
- data/examples/rack/html/NamesApp/app/view/ui/namesWindow.js +0 -92
- data/examples/rack/html/NamesApp/designer.html +0 -19
- data/examples/rack/html/NamesApp/designer.js +0 -32
- data/examples/rack/html/NamesApp/designer_includeOrder.txt +0 -3
- data/examples/rack/html/names.xds +0 -275
data/Gemfile
CHANGED
data/README.markdown
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
This is an attempt to implement **Ext.Direct** (see http://www.sencha.com/products/extjs/extdirect for more info)
|
2
|
+
|
3
|
+
I wanted to have a library that did not have to many dependencies.
|
4
|
+
|
5
|
+
The idea is very simple:
|
6
|
+
|
7
|
+
> 1. add an **'api'** and **'router'** endpoint to your backend.
|
8
|
+
> 2. expose your classes.
|
9
|
+
|
10
|
+
and you are set
|
11
|
+
|
12
|
+
#INSTALL#
|
13
|
+
gem install ruby_ext_direct
|
14
|
+
---
|
15
|
+
|
16
|
+
#Example:#
|
17
|
+
(For more [examples](https://github.com/mehmetc/ruby_ext_direct_examples "EXAMPLES") )
|
18
|
+
##A RACK based example##
|
19
|
+
|
20
|
+
###*Gemfile*
|
21
|
+
|
22
|
+
gem 'ruby_ext_direct', :require => 'ext_direct'
|
23
|
+
|
24
|
+
|
25
|
+
###*web_service.rb*
|
26
|
+
|
27
|
+
require 'rubygems'
|
28
|
+
require 'bundler/setup'
|
29
|
+
require 'rack'
|
30
|
+
require 'json'
|
31
|
+
|
32
|
+
require 'ext_direct'
|
33
|
+
|
34
|
+
#Expose all classes in a directory
|
35
|
+
ExtDirect::Api.expose_all("./exposed_classes")
|
36
|
+
|
37
|
+
#Generate a client-side descriptor
|
38
|
+
map '/api' do
|
39
|
+
run Proc.new { |env|
|
40
|
+
[200, {'Content-Type' => 'text/json'}, [ExtDirect::Api.to_json]]
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
44
|
+
#Route request to methods
|
45
|
+
map '/router' do
|
46
|
+
run Proc.new { |env|
|
47
|
+
result = ''
|
48
|
+
|
49
|
+
req = Rack::Request.new(env)
|
50
|
+
if req.post?
|
51
|
+
data = env["rack.input"].gets
|
52
|
+
result = ExtDirect::Router.route(data)
|
53
|
+
end
|
54
|
+
|
55
|
+
[200, {'Content-Type' => 'text/html'}, [result.to_json]]
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
59
|
+
TODO: add documentation
|
60
|
+
TODO: add rails engine
|
data/lib/ext_direct/api.rb
CHANGED
@@ -4,16 +4,17 @@ module ExtDirect
|
|
4
4
|
# Simply expose a class
|
5
5
|
# @author Mehmet Celik
|
6
6
|
class Api
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
@exposed_api_raw = nil
|
8
|
+
@router_url = '/router'
|
9
|
+
|
10
|
+
# Expose methods from a class and his ancestor, if class was inherited
|
10
11
|
#
|
11
12
|
# @author Mehmet Celik
|
12
13
|
# @param [Class] class that needs to be exposed
|
13
14
|
# @param [Hash] instructions to how to expose the class. For now just the ':only' key is accepted.
|
14
15
|
# @return [Hash] returns a list of exposed classes
|
15
16
|
def self.expose(class_to_expose, options = {})
|
16
|
-
@
|
17
|
+
@exposed_api_raw = {} if @exposed_api_raw.nil?
|
17
18
|
|
18
19
|
methods = []
|
19
20
|
|
@@ -21,16 +22,36 @@ module ExtDirect
|
|
21
22
|
raw_methods = options[:only] || []
|
22
23
|
else
|
23
24
|
raw_methods = class_to_expose.instance_methods(false) - (options[:except] || [])
|
25
|
+
raw_methods += class_to_expose.methods(false) - (options[:except] || [])
|
26
|
+
raw_methods += class_to_expose.ancestors[1].methods(false) - (options[:except] || [])
|
27
|
+
raw_methods += class_to_expose.ancestors[1].instance_methods(false) - (options[:except] || [])
|
24
28
|
end
|
25
29
|
|
26
30
|
raw_methods.uniq!
|
27
31
|
raw_methods.each do |m|
|
28
32
|
name = m
|
29
|
-
|
30
|
-
|
33
|
+
parameters = []
|
34
|
+
method_to_run = nil
|
35
|
+
|
36
|
+
if class_to_expose.methods(false).include?(m)
|
37
|
+
method_to_run = class_to_expose.method(m)
|
38
|
+
elsif class_to_expose.instance_methods(false).include?(m)
|
39
|
+
method_to_run = class_to_expose.instance_method(m)
|
40
|
+
elsif class_to_expose.ancestors[1].methods(false).include?(m)
|
41
|
+
method_to_run = class_to_expose.ancestors[1].method(m)
|
42
|
+
elsif class_to_expose.ancestors[1].instance_methods(false).include?(m)
|
43
|
+
method_to_run = class_to_expose.ancestors[1].instance_method(m)
|
44
|
+
end
|
45
|
+
|
46
|
+
unless method_to_run.nil?
|
47
|
+
method_to_run.parameters.each do |p|
|
48
|
+
parameters << {:name => p[1].to_s, :optional => p[0] == :opt}
|
49
|
+
end
|
50
|
+
end
|
51
|
+
methods << {:name => name, :parameters => parameters}
|
31
52
|
end
|
32
53
|
|
33
|
-
@
|
54
|
+
@exposed_api_raw.store(class_to_expose.name, methods)
|
34
55
|
end
|
35
56
|
|
36
57
|
# Expose all classes in a directory(conviniance method)
|
@@ -38,7 +59,7 @@ module ExtDirect
|
|
38
59
|
# @author Mehmet Celik
|
39
60
|
# @param [String] Directory where all classes are stored
|
40
61
|
def self.expose_all(class_dir)
|
41
|
-
@
|
62
|
+
@exposed_api_raw = {}
|
42
63
|
|
43
64
|
Dir.glob("#{class_dir}/**/*.rb").each do |r|
|
44
65
|
rr = r.split("#{class_dir}/")[1].gsub('.rb','')
|
@@ -64,9 +85,46 @@ module ExtDirect
|
|
64
85
|
# @author Mehmet Celik
|
65
86
|
# @return [Hash] exposed classes
|
66
87
|
def self.to_raw
|
67
|
-
|
88
|
+
|
89
|
+
api = {:url => @router_url || '/router',
|
68
90
|
:type => 'remoting',
|
69
|
-
:actions =>
|
91
|
+
:actions => self.exposed_api}
|
92
|
+
end
|
93
|
+
# Set the router url
|
94
|
+
|
95
|
+
# @author Mehmet Celik
|
96
|
+
# @param [String] router url defaults to '/router'
|
97
|
+
def self.router_url=(url = '/router')
|
98
|
+
@router_url = url
|
99
|
+
end
|
100
|
+
|
101
|
+
# Get the router url
|
102
|
+
|
103
|
+
# @author Mehmet Celik
|
104
|
+
# @return [String] router url
|
105
|
+
def self.router_url
|
106
|
+
@router_url
|
107
|
+
end
|
108
|
+
|
109
|
+
# TODO
|
110
|
+
|
111
|
+
# @author Mehmet Celik
|
112
|
+
# @param [String] router url defaults to '/router'
|
113
|
+
# @return [Hash] exposed API data
|
114
|
+
def self.exposed_api(show_parameters = false)
|
115
|
+
result = @exposed_api_raw
|
116
|
+
unless show_parameters
|
117
|
+
result = {}
|
118
|
+
@exposed_api_raw.each do |k,v|
|
119
|
+
methods = []
|
120
|
+
v.each do |method|
|
121
|
+
methods << {:name => method[:name], :len => method[:parameters].size}
|
122
|
+
end
|
123
|
+
result.store(k,methods)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
result
|
70
128
|
end
|
71
129
|
end
|
72
130
|
end
|
data/lib/ext_direct/router.rb
CHANGED
@@ -35,12 +35,32 @@ module ExtDirect
|
|
35
35
|
klass = self.class.const_get(params[:klass_name])
|
36
36
|
#call method on class
|
37
37
|
klass_instance = klass.new
|
38
|
-
|
38
|
+
|
39
|
+
method_to_call = nil
|
40
|
+
|
41
|
+
method_to_call_name = params[:method_to_call_name].to_sym
|
42
|
+
=begin
|
43
|
+
if klass_instance.methods(false).include?(method_to_call_name)
|
44
|
+
method_to_call = klass_instance.method(method_to_call_name)
|
45
|
+
elsif klass_instance.instance_methods(false).include?( params[:method_to_call_name].to_sym)
|
46
|
+
method_to_call = klass_instance.instance_method(method_to_call_name)
|
47
|
+
elsif klass_instance.ancestors[1].methods(false).include?(method_to_call_name)
|
48
|
+
method_to_call = klass_instance.ancestors[1].method(method_to_call_name)
|
49
|
+
elsif klass_instance.ancestors[1].instance_methods(false).include?(method_to_call_name)
|
50
|
+
method_to_call = klass_instance.ancestors[1].instance_method(method_to_call_name)
|
51
|
+
end
|
52
|
+
=end
|
53
|
+
|
54
|
+
|
55
|
+
# method_to_call = klass_instance.method(params[:method_to_call_name].to_sym)
|
56
|
+
method_to_call = klass_instance.method(method_to_call_name)
|
39
57
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
58
|
+
unless method_to_call.nil?
|
59
|
+
if method_to_call.parameters.size > 0
|
60
|
+
data = method_to_call.call(params[:args]) || []
|
61
|
+
else
|
62
|
+
data = method_to_call.call || []
|
63
|
+
end
|
44
64
|
end
|
45
65
|
|
46
66
|
response = {
|
data/lib/ext_direct/version.rb
CHANGED
data/ruby_ext_direct.gemspec
CHANGED
data/test/test_ext_direct.rb
CHANGED
@@ -14,6 +14,8 @@ class MyClass
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
+
class InheritedFromMyClass < MyClass
|
18
|
+
end
|
17
19
|
|
18
20
|
|
19
21
|
class TestExtDirect < Test::Unit::TestCase
|
@@ -125,5 +127,22 @@ class TestExtDirect < Test::Unit::TestCase
|
|
125
127
|
assert_equal(expected, result)
|
126
128
|
end
|
127
129
|
end
|
130
|
+
|
131
|
+
context 'Calling methods in sub classes' do
|
132
|
+
setup do
|
133
|
+
@request_without_arguments = "{\"action\":\"InheritedFromMyClass\",\"method\":\"method_without_arguments\",\"data\":null,\"type\":\"rpc\",\"tid\":1}"
|
134
|
+
ExtDirect::Api.expose InheritedFromMyClass
|
135
|
+
end
|
136
|
+
|
137
|
+
should "call method without parameters" do
|
138
|
+
expected = "method_without_arguments called"
|
139
|
+
|
140
|
+
result = ExtDirect::Router.route(@request_without_arguments)[:result]
|
141
|
+
|
142
|
+
assert_equal(expected, result)
|
143
|
+
end
|
144
|
+
|
145
|
+
|
146
|
+
end
|
128
147
|
end
|
129
148
|
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: ruby_ext_direct
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.0.
|
5
|
+
version: 0.0.3
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Mehmet Celik
|
@@ -10,10 +10,19 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date:
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
date: 2012-03-22 00:00:00 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: json
|
17
|
+
prerelease: false
|
18
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
19
|
+
none: false
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
type: :runtime
|
25
|
+
version_requirements: *id001
|
17
26
|
description: An attempt to implement Ext.Direct from Sencha
|
18
27
|
email:
|
19
28
|
- mehmet@celik.be
|
@@ -26,7 +35,7 @@ extra_rdoc_files: []
|
|
26
35
|
files:
|
27
36
|
- .gitignore
|
28
37
|
- Gemfile
|
29
|
-
- README
|
38
|
+
- README.markdown
|
30
39
|
- Rakefile
|
31
40
|
- doc/ExtDirect.html
|
32
41
|
- doc/ExtDirect/Api.html
|
@@ -46,39 +55,12 @@ files:
|
|
46
55
|
- doc/js/jquery.js
|
47
56
|
- doc/method_list.html
|
48
57
|
- doc/top-level-namespace.html
|
49
|
-
- examples/API/Gemfile
|
50
|
-
- examples/API/app/actions/api_action.rb
|
51
|
-
- examples/API/app/actions/home_action.rb
|
52
|
-
- examples/API/app/actions/router_action.rb
|
53
|
-
- examples/API/application.rb
|
54
|
-
- examples/API/config.ru
|
55
|
-
- examples/API/config/database.yml
|
56
|
-
- examples/API/config/routes.rb
|
57
|
-
- examples/API/public/NamesApp/app/store/NamesStore.js
|
58
|
-
- examples/API/public/NamesApp/app/view/namesWindow.js
|
59
|
-
- examples/API/public/NamesApp/app/view/ui/namesWindow.js
|
60
|
-
- examples/API/public/NamesApp/designer.html
|
61
|
-
- examples/API/public/NamesApp/designer.js
|
62
|
-
- examples/API/public/NamesApp/designer_includeOrder.txt
|
63
|
-
- examples/API/public/namesApp.xds
|
64
|
-
- examples/rack/config.ru
|
65
|
-
- examples/rack/exposed_classes/countries.rb
|
66
|
-
- examples/rack/exposed_classes/names.rb
|
67
|
-
- examples/rack/html/.DS_Store
|
68
|
-
- examples/rack/html/NamesApp/app/store/NamesStore.js
|
69
|
-
- examples/rack/html/NamesApp/app/view/namesWindow.js
|
70
|
-
- examples/rack/html/NamesApp/app/view/ui/namesWindow.js
|
71
|
-
- examples/rack/html/NamesApp/designer.html
|
72
|
-
- examples/rack/html/NamesApp/designer.js
|
73
|
-
- examples/rack/html/NamesApp/designer_includeOrder.txt
|
74
|
-
- examples/rack/html/names.xds
|
75
58
|
- lib/ext_direct.rb
|
76
59
|
- lib/ext_direct/api.rb
|
77
60
|
- lib/ext_direct/router.rb
|
78
61
|
- lib/ext_direct/version.rb
|
79
62
|
- ruby_ext_direct.gemspec
|
80
63
|
- test/test_ext_direct.rb
|
81
|
-
has_rdoc: true
|
82
64
|
homepage: https://github.com/mehmetc/ruby_ext_direct
|
83
65
|
licenses: []
|
84
66
|
|
@@ -102,9 +84,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
102
84
|
requirements: []
|
103
85
|
|
104
86
|
rubyforge_project: ruby_ext_direct
|
105
|
-
rubygems_version: 1.
|
87
|
+
rubygems_version: 1.8.15
|
106
88
|
signing_key:
|
107
89
|
specification_version: 3
|
108
90
|
summary: An attempt to implement Ext.Direct from Sencha
|
109
91
|
test_files:
|
110
92
|
- test/test_ext_direct.rb
|
93
|
+
has_rdoc:
|
data/README
DELETED
@@ -1,12 +0,0 @@
|
|
1
|
-
This is an attempt to implement Ext.Direct (see http://www.sencha.com/products/extjs/extdirect for more info)
|
2
|
-
|
3
|
-
I wanted to have a library that did not explicitly bind to any ORM(like ActiveRecord, Datamapper, ...).
|
4
|
-
The idea is very simple just add an 'api' and 'router' path to your backend point to your exposed classes and you are set.
|
5
|
-
|
6
|
-
Example: (See examples directory for more)
|
7
|
-
Add this to your Gemfile
|
8
|
-
gem 'ruby_ext_direct', :require => 'ext_direct'
|
9
|
-
|
10
|
-
|
11
|
-
TODO: add documentation
|
12
|
-
TODO: add rails engine
|
data/examples/API/Gemfile
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
source :rubygems
|
2
|
-
|
3
|
-
gem 'cramp'
|
4
|
-
|
5
|
-
# Async webserver for running a cramp application
|
6
|
-
gem 'thin'
|
7
|
-
|
8
|
-
# Rack based routing
|
9
|
-
gem 'http_router'
|
10
|
-
|
11
|
-
# Collection of async-proof rack middlewares - https://github.com/rkh/async-rack.git
|
12
|
-
gem 'async-rack'
|
13
|
-
|
14
|
-
# For async Active Record models
|
15
|
-
gem 'mysql2', '~> 0.2.11'
|
16
|
-
gem 'activerecord', :require => 'active_record'
|
17
|
-
|
18
|
-
gem 'ext_direct', '0.0.1'
|
19
|
-
|
20
|
-
# Using Fibers + async callbacks to emulate synchronous programming
|
21
|
-
# gem 'em-synchrony'
|
22
|
-
|
23
|
-
# Generic interface to multiple Ruby template engines - https://github.com/rtomayko/tilt
|
24
|
-
# gem 'tilt'
|
25
|
-
|
26
|
-
group :development do
|
27
|
-
# Development gems
|
28
|
-
# gem 'ruby-debug19'
|
29
|
-
end
|
@@ -1,18 +0,0 @@
|
|
1
|
-
#require 'ext_direct'
|
2
|
-
|
3
|
-
class ApiAction < Cramp::Action
|
4
|
-
on_start :render_api
|
5
|
-
|
6
|
-
def render_api
|
7
|
-
# ExtDirect::Api.expose_all "/Users/mehmetc/Sources/LBT/ext_direct/examples/rack/exposed_classes"
|
8
|
-
render ExtDirect::Api.to_json
|
9
|
-
finish
|
10
|
-
end
|
11
|
-
|
12
|
-
def respond_with
|
13
|
-
# content_type = params[:format] == 'xml' ? 'application/xml' : 'application/json'
|
14
|
-
[200, {'Content-Type' => 'application/json'}]
|
15
|
-
end
|
16
|
-
|
17
|
-
|
18
|
-
end
|
@@ -1,11 +0,0 @@
|
|
1
|
-
class HomeAction < Cramp::Action
|
2
|
-
use_fiber_pool do |pool|
|
3
|
-
# Checkin database connection after each callback
|
4
|
-
pool.generic_callbacks << proc { ActiveRecord::Base.clear_active_connections! }
|
5
|
-
end
|
6
|
-
|
7
|
-
def start
|
8
|
-
render "Hello World!"
|
9
|
-
finish
|
10
|
-
end
|
11
|
-
end
|
@@ -1,18 +0,0 @@
|
|
1
|
-
class RouterAction < Cramp::Action
|
2
|
-
on_start :route_data_to_class
|
3
|
-
|
4
|
-
def route_data_to_class
|
5
|
-
ExtDirect::Api.expose_all "/Users/mehmetc/Sources/LBT/ext_direct/examples/rack/exposed_classes"
|
6
|
-
data = ''
|
7
|
-
if request.post?
|
8
|
-
data = request.env['rack.input'].gets
|
9
|
-
result = ExtDirect::Router.route(data)
|
10
|
-
end
|
11
|
-
|
12
|
-
render result.to_json
|
13
|
-
end
|
14
|
-
|
15
|
-
def respond_with
|
16
|
-
[200, {'Content-Type' => 'application/json'}]
|
17
|
-
end
|
18
|
-
end
|