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.
Files changed (34) hide show
  1. data/Gemfile +1 -1
  2. data/README.markdown +60 -0
  3. data/lib/ext_direct/api.rb +68 -10
  4. data/lib/ext_direct/router.rb +25 -5
  5. data/lib/ext_direct/version.rb +1 -1
  6. data/ruby_ext_direct.gemspec +1 -0
  7. data/test/test_ext_direct.rb +19 -0
  8. metadata +17 -34
  9. data/README +0 -12
  10. data/examples/API/Gemfile +0 -29
  11. data/examples/API/app/actions/api_action.rb +0 -18
  12. data/examples/API/app/actions/home_action.rb +0 -11
  13. data/examples/API/app/actions/router_action.rb +0 -18
  14. data/examples/API/application.rb +0 -37
  15. data/examples/API/config.ru +0 -25
  16. data/examples/API/config/database.yml +0 -6
  17. data/examples/API/config/routes.rb +0 -6
  18. data/examples/API/public/NamesApp/app/store/NamesStore.js +0 -48
  19. data/examples/API/public/NamesApp/app/view/namesWindow.js +0 -21
  20. data/examples/API/public/NamesApp/app/view/ui/namesWindow.js +0 -58
  21. data/examples/API/public/NamesApp/designer.html +0 -19
  22. data/examples/API/public/NamesApp/designer.js +0 -32
  23. data/examples/API/public/NamesApp/designer_includeOrder.txt +0 -3
  24. data/examples/API/public/namesApp.xds +0 -200
  25. data/examples/rack/config.ru +0 -40
  26. data/examples/rack/exposed_classes/countries.rb +0 -10
  27. data/examples/rack/exposed_classes/names.rb +0 -82
  28. data/examples/rack/html/NamesApp/app/store/NamesStore.js +0 -56
  29. data/examples/rack/html/NamesApp/app/view/namesWindow.js +0 -49
  30. data/examples/rack/html/NamesApp/app/view/ui/namesWindow.js +0 -92
  31. data/examples/rack/html/NamesApp/designer.html +0 -19
  32. data/examples/rack/html/NamesApp/designer.js +0 -32
  33. data/examples/rack/html/NamesApp/designer_includeOrder.txt +0 -3
  34. data/examples/rack/html/names.xds +0 -275
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
1
  source "http://rubygems.org"
2
2
 
3
- # Specify your gem's dependencies in ext_direct.gemspec
3
+ # Specify your gem's dependencies in ruby_ext_direct.gemspec
4
4
  gemspec
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
@@ -4,16 +4,17 @@ module ExtDirect
4
4
  # Simply expose a class
5
5
  # @author Mehmet Celik
6
6
  class Api
7
- attr_reader :exposed_api
8
-
9
- # Expose a class
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
- @exposed_api = {} if @exposed_api.nil?
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
- len = class_to_expose.instance_method(m).parameters.size
30
- methods << {:name => name, :len => len}
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
- @exposed_api.store(class_to_expose.name, methods)
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
- @exposed_api = {}
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
- api = {:url => '/router',
88
+
89
+ api = {:url => @router_url || '/router',
68
90
  :type => 'remoting',
69
- :actions => @exposed_api}
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
@@ -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
- method_to_call = klass_instance.method(params[:method_to_call_name].to_sym)
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
- if method_to_call.parameters.size > 0
41
- data = method_to_call.call(params[:args])
42
- else
43
- data = method_to_call.call
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 = {
@@ -1,3 +1,3 @@
1
1
  module ExtDirect
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -21,4 +21,5 @@ Gem::Specification.new do |s|
21
21
  # specify any dependencies here; for example:
22
22
  # s.add_development_dependency "rspec"
23
23
  # s.add_runtime_dependency "rest-client"
24
+ s.add_dependency("json")
24
25
  end
@@ -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.2
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: 2011-10-23 00:00:00 +02:00
14
- default_executable:
15
- dependencies: []
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.6.2
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