ruby_ext_direct 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. data/.gitignore +7 -0
  2. data/Gemfile +4 -0
  3. data/README +5 -0
  4. data/Rakefile +1 -0
  5. data/examples/API/Gemfile +29 -0
  6. data/examples/API/app/actions/api_action.rb +18 -0
  7. data/examples/API/app/actions/home_action.rb +11 -0
  8. data/examples/API/app/actions/router_action.rb +18 -0
  9. data/examples/API/application.rb +37 -0
  10. data/examples/API/config/database.yml +6 -0
  11. data/examples/API/config/routes.rb +6 -0
  12. data/examples/API/config.ru +25 -0
  13. data/examples/API/public/NamesApp/app/store/NamesStore.js +48 -0
  14. data/examples/API/public/NamesApp/app/view/namesWindow.js +21 -0
  15. data/examples/API/public/NamesApp/app/view/ui/namesWindow.js +58 -0
  16. data/examples/API/public/NamesApp/designer.html +19 -0
  17. data/examples/API/public/NamesApp/designer.js +32 -0
  18. data/examples/API/public/NamesApp/designer_includeOrder.txt +3 -0
  19. data/examples/API/public/namesApp.xds +200 -0
  20. data/examples/rack/config.ru +40 -0
  21. data/examples/rack/exposed_classes/countries.rb +10 -0
  22. data/examples/rack/exposed_classes/names.rb +82 -0
  23. data/examples/rack/html/.DS_Store +0 -0
  24. data/examples/rack/html/NamesApp/app/store/NamesStore.js +56 -0
  25. data/examples/rack/html/NamesApp/app/view/namesWindow.js +49 -0
  26. data/examples/rack/html/NamesApp/app/view/ui/namesWindow.js +92 -0
  27. data/examples/rack/html/NamesApp/designer.html +19 -0
  28. data/examples/rack/html/NamesApp/designer.js +32 -0
  29. data/examples/rack/html/NamesApp/designer_includeOrder.txt +3 -0
  30. data/examples/rack/html/names.xds +275 -0
  31. data/lib/ext_direct/api.rb +53 -0
  32. data/lib/ext_direct/router.rb +97 -0
  33. data/lib/ext_direct/version.rb +3 -0
  34. data/lib/ext_direct.rb +13 -0
  35. data/ruby_ext_direct.gemspec +24 -0
  36. data/test/test_ext_direct.rb +129 -0
  37. metadata +92 -0
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .DS_Store
6
+ examples/rack/html/tmp
7
+ examples/rack/data.yml
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in ext_direct.gemspec
4
+ gemspec
data/README ADDED
@@ -0,0 +1,5 @@
1
+ This is an attempt to implement Ext.Direct (see http://www.sencha.com/products/extjs/extdirect for more info)
2
+
3
+
4
+ TODO: add documentation
5
+ TODO: add rails engine
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,29 @@
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
@@ -0,0 +1,18 @@
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
@@ -0,0 +1,11 @@
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
@@ -0,0 +1,18 @@
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
@@ -0,0 +1,37 @@
1
+ require "rubygems"
2
+ require "bundler"
3
+
4
+ module API
5
+ class Application
6
+
7
+ def self.root(path = nil)
8
+ @_root ||= File.expand_path(File.dirname(__FILE__))
9
+ path ? File.join(@_root, path.to_s) : @_root
10
+ end
11
+
12
+ def self.env
13
+ @_env ||= ENV['RACK_ENV'] || 'development'
14
+ end
15
+
16
+ def self.routes
17
+ @_routes ||= eval(File.read('./config/routes.rb'))
18
+ end
19
+
20
+ def self.database_config
21
+ @_database_config ||= YAML.load(File.read('./config/database.yml')).with_indifferent_access
22
+ end
23
+
24
+ # Initialize the application
25
+ def self.initialize!
26
+ ActiveRecord::Base.configurations = API::Application.database_config
27
+ ActiveRecord::Base.establish_connection(API::Application.env)
28
+ ExtDirect::Api.expose_all "/Users/mehmetc/Sources/LBT/ext_direct/examples/rack/exposed_classes"
29
+ end
30
+
31
+ end
32
+ end
33
+
34
+ Bundler.require(:default, API::Application.env)
35
+
36
+ # Preload application classes
37
+ Dir['./app/**/*.rb'].each {|f| require f}
@@ -0,0 +1,6 @@
1
+ development:
2
+ adapter: em_mysql2
3
+ database: API_development
4
+ host: localhost
5
+ username: root
6
+ pool: 100
@@ -0,0 +1,6 @@
1
+ # Check out https://github.com/joshbuddy/http_router for more information on HttpRouter
2
+ HttpRouter.new do
3
+ add('/api').to(ApiAction)
4
+ add('/router').to(RouterAction)
5
+ add('/').to(HomeAction)
6
+ end
@@ -0,0 +1,25 @@
1
+ require './application'
2
+ API::Application.initialize!
3
+
4
+ # Development middlewares
5
+ if API::Application.env == 'development'
6
+ use AsyncRack::CommonLogger
7
+
8
+ # Enable code reloading on every request
9
+ use Rack::Reloader, 0
10
+
11
+ # Serve assets from /public
12
+ use Rack::Static, :urls => ["/NamesApp", "/javascripts"], :root => API::Application.root(:public)
13
+ end
14
+
15
+ # Running thin :
16
+ #
17
+ # bundle exec thin --max-persistent-conns 1024 --timeout 0 -R config.ru start
18
+ #
19
+ # Vebose mode :
20
+ #
21
+ # Very useful when you want to view all the data being sent/received by thin
22
+ #
23
+ # bundle exec thin --max-persistent-conns 1024 --timeout 0 -V -R config.ru start
24
+ #
25
+ run API::Application.routes
@@ -0,0 +1,48 @@
1
+ /*
2
+ * File: app/store/NamesStore.js
3
+ * Date: Tue Sep 06 2011 15:09:45 GMT+0200 (CEST)
4
+ *
5
+ * This file was generated by Ext Designer version 1.2.0.
6
+ * http://www.sencha.com/products/designer/
7
+ *
8
+ * This file will be auto-generated each and everytime you export.
9
+ *
10
+ * Do NOT hand edit this file.
11
+ */
12
+
13
+ Ext.define('NamesApp.store.NamesStore', {
14
+ extend: 'Ext.data.Store',
15
+
16
+ constructor: function(cfg) {
17
+ var me = this;
18
+ cfg = cfg || {};
19
+ me.callParent([Ext.apply({
20
+ autoLoad: true,
21
+ storeId: 'NamesStore',
22
+ proxy: {
23
+ type: 'direct',
24
+ api: {
25
+ read: Names.get,
26
+ update: Names.set
27
+ },
28
+ reader: {
29
+ type: 'json'
30
+ }
31
+ },
32
+ fields: [
33
+ {
34
+ name: 'name',
35
+ type: 'string'
36
+ },
37
+ {
38
+ name: 'address',
39
+ type: 'string'
40
+ },
41
+ {
42
+ name: 'country',
43
+ type: 'string'
44
+ }
45
+ ]
46
+ }, cfg)]);
47
+ }
48
+ });
@@ -0,0 +1,21 @@
1
+ /*
2
+ * File: app/view/namesWindow.js
3
+ * Date: Tue Sep 06 2011 15:09:45 GMT+0200 (CEST)
4
+ *
5
+ * This file was generated by Ext Designer version 1.2.0.
6
+ * http://www.sencha.com/products/designer/
7
+ *
8
+ * This file will be generated the first time you export.
9
+ *
10
+ * You should implement event handling and custom methods in this
11
+ * class.
12
+ */
13
+
14
+ Ext.define('NamesApp.view.namesWindow', {
15
+ extend: 'NamesApp.view.ui.namesWindow',
16
+
17
+ initComponent: function() {
18
+ var me = this;
19
+ me.callParent(arguments);
20
+ }
21
+ });
@@ -0,0 +1,58 @@
1
+ /*
2
+ * File: app/view/ui/namesWindow.js
3
+ * Date: Tue Sep 06 2011 15:09:45 GMT+0200 (CEST)
4
+ *
5
+ * This file was generated by Ext Designer version 1.2.0.
6
+ * http://www.sencha.com/products/designer/
7
+ *
8
+ * This file will be auto-generated each and everytime you export.
9
+ *
10
+ * Do NOT hand edit this file.
11
+ */
12
+
13
+ Ext.define('NamesApp.view.ui.namesWindow', {
14
+ extend: 'Ext.window.Window',
15
+
16
+ height: 541,
17
+ id: 'namesWindow',
18
+ width: 797,
19
+ layout: {
20
+ type: 'fit'
21
+ },
22
+ title: 'All Names',
23
+
24
+ initComponent: function() {
25
+ var me = this;
26
+ me.items = [
27
+ {
28
+ xtype: 'gridpanel',
29
+ id: 'namesGrid',
30
+ title: 'Names Grid',
31
+ store: 'NamesStore',
32
+ viewConfig: {
33
+
34
+ },
35
+ columns: [
36
+ {
37
+ xtype: 'gridcolumn',
38
+ width: 186,
39
+ dataIndex: 'name',
40
+ text: 'Name'
41
+ },
42
+ {
43
+ xtype: 'gridcolumn',
44
+ width: 453,
45
+ dataIndex: 'address',
46
+ text: 'Address'
47
+ },
48
+ {
49
+ xtype: 'gridcolumn',
50
+ dataIndex: 'country',
51
+ text: 'Country'
52
+ }
53
+ ]
54
+ }
55
+ ];
56
+ me.callParent(arguments);
57
+ }
58
+ });
@@ -0,0 +1,19 @@
1
+ <!DOCTYPE html>
2
+
3
+ <!-- Auto Generated with Ext Designer -->
4
+ <!-- Modifications to this file will be overwritten. -->
5
+ <html>
6
+ <head>
7
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
8
+ <title>namesApp.xds</title>
9
+ <link rel="stylesheet" type="text/css" href="http://extjs.cachefly.net/ext-4.0.2a/resources/css/ext-all.css"/>
10
+ <script type="text/javascript" src="http://extjs.cachefly.net/ext-4.0.2a/ext-all-debug.js"></script>
11
+ <script type="text/javascript">
12
+ Ext.ns("REMOTING_API");
13
+ REMOTING_API = {"descriptor":"REMOTING_API","url":"/router","type":"remoting","actions":{"Countries":[{"name":"countries","len":0},{"name":"get","len":0}],"Names":[{"name":"names","len":0},{"name":"get","len":0},{"name":"set","len":1}]}};
14
+ Ext.Direct.addProvider(REMOTING_API);
15
+ </script>
16
+ <script type="text/javascript" src="designer.js"></script>
17
+ </head>
18
+ <body></body>
19
+ </html>
@@ -0,0 +1,32 @@
1
+ /*
2
+ * File: designer.js
3
+ * Date: Tue Sep 06 2011 15:09:45 GMT+0200 (CEST)
4
+ *
5
+ * This file was generated by Ext Designer version 1.2.0.
6
+ * http://www.sencha.com/products/designer/
7
+ *
8
+ * This file will be auto-generated each and everytime you export.
9
+ *
10
+ * Do NOT hand edit this file.
11
+ */
12
+
13
+ Ext.Loader.setConfig({
14
+ enabled: true
15
+ });
16
+
17
+ Ext.application({
18
+ name: 'NamesApp',
19
+
20
+ stores: [
21
+ 'NamesStore'
22
+ ],
23
+
24
+ launch: function() {
25
+ Ext.QuickTips.init();
26
+
27
+ var cmp1 = Ext.create('NamesApp.view.namesWindow', {
28
+ renderTo: Ext.getBody()
29
+ });
30
+ cmp1.show();
31
+ }
32
+ });
@@ -0,0 +1,3 @@
1
+ <script type="text/javascript" src="app/view/ui/namesWindow.js"></script>
2
+ <script type="text/javascript" src="app/view/namesWindow.js"></script>
3
+ <script type="text/javascript" src="app/store/NamesStore.js"></script>
@@ -0,0 +1,200 @@
1
+ {
2
+ "name": "names.xds",
3
+ "settings": {
4
+ "urlPrefix": "http://localhost/",
5
+ "directAPI": "http://localhost:3000/api",
6
+ "spacesToIndent": "4",
7
+ "codeGenFormat": "Class",
8
+ "exportPath": "./NamesApp",
9
+ "extPath": "http://extjs.cachefly.net/ext-4.0.2a/",
10
+ "lineEnding": "LF",
11
+ "instantiateStore": true,
12
+ "exportXDSFiles": true,
13
+ "genTimestamps": true,
14
+ "appName": "NamesApp"
15
+ },
16
+ "xdsVersion": "1.2.0",
17
+ "components": [
18
+ {
19
+ "id": "ExtBox1-ext-gen2626",
20
+ "type": "window",
21
+ "reference": {
22
+ "name": "items",
23
+ "type": "array"
24
+ },
25
+ "codeClass": null,
26
+ "userConfig": {
27
+ "height": 541,
28
+ "id": "namesWindow",
29
+ "width": 797,
30
+ "layout": "fit",
31
+ "title": "All Names",
32
+ "designer|userClassName": "namesWindow"
33
+ },
34
+ "cn": [
35
+ {
36
+ "id": "ExtBox1-ext-gen2817",
37
+ "type": "gridpanel",
38
+ "reference": {
39
+ "name": "items",
40
+ "type": "array"
41
+ },
42
+ "codeClass": null,
43
+ "userConfig": {
44
+ "id": "namesGrid",
45
+ "title": "Names Grid",
46
+ "store": "NamesStore",
47
+ "designer|userClassName": "MyGridPanel"
48
+ },
49
+ "cn": [
50
+ {
51
+ "id": "ExtBox1-ext-gen2854",
52
+ "type": "gridview",
53
+ "reference": {
54
+ "name": "viewConfig",
55
+ "type": "object"
56
+ },
57
+ "codeClass": null,
58
+ "userConfig": {
59
+ "designer|userClassName": "MyGridView"
60
+ }
61
+ },
62
+ {
63
+ "id": "ExtBox1-ext-gen3478",
64
+ "type": "gridcolumn",
65
+ "reference": {
66
+ "name": "columns",
67
+ "type": "array"
68
+ },
69
+ "codeClass": null,
70
+ "userConfig": {
71
+ "width": 186,
72
+ "dataIndex": "name",
73
+ "text": "Name",
74
+ "designer|userClassName": "MyColumn1"
75
+ }
76
+ },
77
+ {
78
+ "id": "ExtBox1-ext-gen3487",
79
+ "type": "gridcolumn",
80
+ "reference": {
81
+ "name": "columns",
82
+ "type": "array"
83
+ },
84
+ "codeClass": null,
85
+ "userConfig": {
86
+ "width": 453,
87
+ "dataIndex": "address",
88
+ "text": "Address",
89
+ "designer|userClassName": "MyColumn2"
90
+ }
91
+ },
92
+ {
93
+ "id": "ExtBox1-ext-gen3496",
94
+ "type": "gridcolumn",
95
+ "reference": {
96
+ "name": "columns",
97
+ "type": "array"
98
+ },
99
+ "codeClass": null,
100
+ "userConfig": {
101
+ "dataIndex": "country",
102
+ "text": "Country",
103
+ "designer|userClassName": "MyColumn3"
104
+ }
105
+ }
106
+ ]
107
+ }
108
+ ]
109
+ }
110
+ ],
111
+ "stores": [
112
+ {
113
+ "id": "ExtBox1-ext-gen1666",
114
+ "type": "directstore",
115
+ "reference": {
116
+ "name": "items",
117
+ "type": "array"
118
+ },
119
+ "codeClass": null,
120
+ "userConfig": {
121
+ "autoLoad": true,
122
+ "storeId": "NamesStore",
123
+ "designer|userClassName": "NamesStore"
124
+ },
125
+ "cn": [
126
+ {
127
+ "id": "ExtBox1-ext-gen1670",
128
+ "type": "directproxy",
129
+ "reference": {
130
+ "name": "proxy",
131
+ "type": "object"
132
+ },
133
+ "codeClass": null,
134
+ "userConfig": {
135
+ "api": "{read:Names.get,\nupdate:Names.set}",
136
+ "directFn": null,
137
+ "designer|userClassName": "Direct Proxy"
138
+ },
139
+ "cn": [
140
+ {
141
+ "id": "ExtBox1-ext-gen1676",
142
+ "type": "jsonreader",
143
+ "reference": {
144
+ "name": "reader",
145
+ "type": "object"
146
+ },
147
+ "codeClass": null,
148
+ "userConfig": {
149
+ "designer|userClassName": "Json Reader"
150
+ }
151
+ }
152
+ ]
153
+ },
154
+ {
155
+ "id": "ExtBox1-ext-gen2110",
156
+ "type": "datafield",
157
+ "reference": {
158
+ "name": "fields",
159
+ "type": "array"
160
+ },
161
+ "codeClass": null,
162
+ "userConfig": {
163
+ "name": "name",
164
+ "type": "string",
165
+ "designer|userClassName": "MyField"
166
+ }
167
+ },
168
+ {
169
+ "id": "ExtBox1-ext-gen2117",
170
+ "type": "datafield",
171
+ "reference": {
172
+ "name": "fields",
173
+ "type": "array"
174
+ },
175
+ "codeClass": null,
176
+ "userConfig": {
177
+ "name": "address",
178
+ "type": "string",
179
+ "designer|userClassName": "MyField1"
180
+ }
181
+ },
182
+ {
183
+ "id": "ExtBox1-ext-gen2124",
184
+ "type": "datafield",
185
+ "reference": {
186
+ "name": "fields",
187
+ "type": "array"
188
+ },
189
+ "codeClass": null,
190
+ "userConfig": {
191
+ "name": "country",
192
+ "type": "string",
193
+ "designer|userClassName": "MyField2"
194
+ }
195
+ }
196
+ ]
197
+ }
198
+ ],
199
+ "framework": "ext40"
200
+ }
@@ -0,0 +1,40 @@
1
+ require 'rubygems'
2
+ require 'json'
3
+ require 'rack'
4
+ require 'ext_direct'
5
+
6
+ require 'pp'
7
+
8
+ ExtDirect::Api.expose_all("./exposed_classes")
9
+
10
+ app = Rack::Builder.new do
11
+ use Rack::ShowExceptions
12
+
13
+ map '/' do
14
+ run Rack::Directory.new('./html')
15
+ end
16
+
17
+ map '/api' do
18
+ run Proc.new { |env|
19
+ [200, {'Content-Type' => 'text/json'}, [ExtDirect::Api.to_json]]
20
+ }
21
+ end
22
+
23
+ map '/router' do
24
+ run Proc.new { |env|
25
+ result = ''
26
+
27
+ req = Rack::Request.new(env)
28
+ if req.post?
29
+ data = env["rack.input"].gets
30
+ pp data
31
+ result = ExtDirect::Router.route(data)
32
+ end
33
+
34
+ [200, {'Content-Type' => 'text/html'}, [result.to_json]]
35
+ }
36
+ end
37
+
38
+ end
39
+
40
+ run app
@@ -0,0 +1,10 @@
1
+ class Countries
2
+ attr_reader :countries
3
+ def initialize
4
+ @countries =[ {'id' => 1, 'code' => 'be', 'value' => 'Belgium'}, {'id' => 2, 'code' => 'us', 'value' => 'United States'}]
5
+ end
6
+
7
+ def get
8
+ @countries
9
+ end
10
+ end