captproton-restfulx 1.2.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/README.rdoc +50 -0
- data/Rakefile +79 -0
- data/VERSION.yml +4 -0
- data/app_generators/rx_app/USAGE +22 -0
- data/app_generators/rx_app/rx_app_generator.rb +110 -0
- data/app_generators/rx_app/templates/actionscript.properties +16 -0
- data/app_generators/rx_app/templates/actionscriptair.properties +16 -0
- data/app_generators/rx_app/templates/app.yaml.erb +12 -0
- data/app_generators/rx_app/templates/default_tasks.rake +38 -0
- data/app_generators/rx_app/templates/empty.txt +0 -0
- data/app_generators/rx_app/templates/expressInstall.swf +0 -0
- data/app_generators/rx_app/templates/flex.properties +2 -0
- data/app_generators/rx_app/templates/generate.rb +17 -0
- data/app_generators/rx_app/templates/html-template/AC_OETags.js +276 -0
- data/app_generators/rx_app/templates/html-template/history/history.css +6 -0
- data/app_generators/rx_app/templates/html-template/history/history.js +645 -0
- data/app_generators/rx_app/templates/html-template/history/historyFrame.html +29 -0
- data/app_generators/rx_app/templates/html-template/index.template.html +121 -0
- data/app_generators/rx_app/templates/html-template/playerProductInstall.swf +0 -0
- data/app_generators/rx_app/templates/index.html.erb +18 -0
- data/app_generators/rx_app/templates/index.yaml +11 -0
- data/app_generators/rx_app/templates/mainair-app.xml +134 -0
- data/app_generators/rx_app/templates/mainapp-config.xml +22 -0
- data/app_generators/rx_app/templates/mainapp.mxml +152 -0
- data/app_generators/rx_app/templates/project-textmate.erb +72 -0
- data/app_generators/rx_app/templates/project.properties +18 -0
- data/app_generators/rx_app/templates/projectair.properties +24 -0
- data/app_generators/rx_app/templates/restfulx.yml +46 -0
- data/app_generators/rx_app/templates/swfobject.js +5 -0
- data/bin/rx-gen +31 -0
- data/lib/restfulx.rb +90 -0
- data/lib/restfulx/active_foo.rb +181 -0
- data/lib/restfulx/active_record_tasks.rb +90 -0
- data/lib/restfulx/active_record_uuid_helper.rb +17 -0
- data/lib/restfulx/configuration.rb +75 -0
- data/lib/restfulx/datamapper_foo.rb +81 -0
- data/lib/restfulx/rails/recipes.rb +60 -0
- data/lib/restfulx/rails/schema_to_yaml.rb +112 -0
- data/lib/restfulx/rails/schema_to_yaml/extensions/enumerable.rb +8 -0
- data/lib/restfulx/rails/schema_to_yaml/settings/config.rb +17 -0
- data/lib/restfulx/rails/schema_to_yaml/settings/core.rb +73 -0
- data/lib/restfulx/rails/swf_helper.rb +59 -0
- data/lib/restfulx/tasks.rb +110 -0
- data/rails_generators/rx_config/USAGE +19 -0
- data/rails_generators/rx_config/rx_config_generator.rb +151 -0
- data/rails_generators/rx_config/templates/actionscript.properties +16 -0
- data/rails_generators/rx_config/templates/actionscriptair.properties +16 -0
- data/rails_generators/rx_config/templates/expressInstall.swf +0 -0
- data/rails_generators/rx_config/templates/flex.properties +2 -0
- data/rails_generators/rx_config/templates/flex_controller.erb +4 -0
- data/rails_generators/rx_config/templates/html-template/AC_OETags.js +276 -0
- data/rails_generators/rx_config/templates/html-template/history/history.css +6 -0
- data/rails_generators/rx_config/templates/html-template/history/history.js +645 -0
- data/rails_generators/rx_config/templates/html-template/history/historyFrame.html +29 -0
- data/rails_generators/rx_config/templates/html-template/index.template.html +121 -0
- data/rails_generators/rx_config/templates/html-template/playerProductInstall.swf +0 -0
- data/rails_generators/rx_config/templates/index.erb +16 -0
- data/rails_generators/rx_config/templates/mainair-app.xml +134 -0
- data/rails_generators/rx_config/templates/mainapp-config.xml +22 -0
- data/rails_generators/rx_config/templates/mainapp.mxml +129 -0
- data/rails_generators/rx_config/templates/project-textmate.erb +72 -0
- data/rails_generators/rx_config/templates/project.properties +18 -0
- data/rails_generators/rx_config/templates/projectair.properties +24 -0
- data/rails_generators/rx_config/templates/restfulx.erb +75 -0
- data/rails_generators/rx_config/templates/restfulx.yml +65 -0
- data/rails_generators/rx_config/templates/restfulx_tasks.rake +9 -0
- data/rails_generators/rx_config/templates/routes.erb +47 -0
- data/rails_generators/rx_config/templates/session_store_flash.erb +1 -0
- data/rails_generators/rx_config/templates/swfobject.js +5 -0
- data/rails_generators/rx_controller/USAGE +10 -0
- data/rails_generators/rx_controller/rx_controller_generator.rb +31 -0
- data/rails_generators/rx_controller/templates/controller.as.erb +38 -0
- data/rails_generators/rx_main_app/USAGE +8 -0
- data/rails_generators/rx_main_app/rx_main_app_generator.rb +60 -0
- data/rails_generators/rx_main_app/templates/mainapp.mxml +129 -0
- data/rails_generators/rx_scaffold/USAGE +35 -0
- data/rails_generators/rx_scaffold/rx_scaffold_generator.rb +242 -0
- data/rails_generators/rx_scaffold/templates/controllers/default.rb.erb +125 -0
- data/rails_generators/rx_scaffold/templates/controllers/resource_controller.rb.erb +23 -0
- data/rails_generators/rx_scaffold/templates/fixtures.yml.erb +39 -0
- data/rails_generators/rx_scaffold/templates/functional_test.rb +45 -0
- data/rails_generators/rx_scaffold/templates/helper_test.rb +4 -0
- data/rails_generators/rx_scaffold/templates/layouts/default.erb +167 -0
- data/rails_generators/rx_scaffold/templates/migration.rb.erb +46 -0
- data/rails_generators/rx_scaffold/templates/model.as.erb +73 -0
- data/rails_generators/rx_scaffold/templates/model.rb.erb +46 -0
- data/rails_generators/rx_yaml_scaffold/USAGE +51 -0
- data/rails_generators/rx_yaml_scaffold/rx_yaml_scaffold_generator.rb +68 -0
- data/rxgen_generators/rx_config/USAGE +5 -0
- data/rxgen_generators/rx_config/rx_config_generator.rb +21 -0
- data/rxgen_generators/rx_controller/USAGE +10 -0
- data/rxgen_generators/rx_controller/rx_controller_generator.rb +41 -0
- data/rxgen_generators/rx_controller/templates/assist.py +65 -0
- data/rxgen_generators/rx_controller/templates/controller.as.erb +38 -0
- data/rxgen_generators/rx_controller/templates/iso8601.py +92 -0
- data/rxgen_generators/rx_controller/templates/restful.py +136 -0
- data/rxgen_generators/rx_main_app/USAGE +8 -0
- data/rxgen_generators/rx_main_app/rx_main_app_generator.rb +65 -0
- data/rxgen_generators/rx_main_app/templates/main.py.erb +29 -0
- data/rxgen_generators/rx_main_app/templates/mainapp.mxml +152 -0
- data/rxgen_generators/rx_scaffold/USAGE +29 -0
- data/rxgen_generators/rx_scaffold/rx_scaffold_generator.rb +194 -0
- data/rxgen_generators/rx_scaffold/templates/controller.py.erb +27 -0
- data/rxgen_generators/rx_scaffold/templates/layouts/default.erb +167 -0
- data/rxgen_generators/rx_scaffold/templates/model.as.erb +73 -0
- data/rxgen_generators/rx_scaffold/templates/model.py.erb +14 -0
- data/rxgen_generators/rx_yaml_scaffold/USAGE +45 -0
- data/rxgen_generators/rx_yaml_scaffold/rx_yaml_scaffold_generator.rb +47 -0
- data/spec/restfulx_spec.rb +4 -0
- data/spec/spec_helper.rb +13 -0
- data/tasks/restfulx.rake +2 -0
- data/test/rails/controllers/application_controller.rb +15 -0
- data/test/rails/controllers/locations_controller.rb +93 -0
- data/test/rails/controllers/notes_controller.rb +96 -0
- data/test/rails/controllers/projects_controller.rb +93 -0
- data/test/rails/controllers/tasks_controller.rb +93 -0
- data/test/rails/controllers/users_controller.rb +93 -0
- data/test/rails/database.yml +4 -0
- data/test/rails/fixtures/locations.yml +8 -0
- data/test/rails/fixtures/notes.yml +17 -0
- data/test/rails/fixtures/projects.yml +25 -0
- data/test/rails/fixtures/simple_properties.yml +19 -0
- data/test/rails/fixtures/tasks.yml +46 -0
- data/test/rails/fixtures/users.yml +13 -0
- data/test/rails/helpers/functional_test_helper.rb +21 -0
- data/test/rails/helpers/test_helper.rb +54 -0
- data/test/rails/helpers/unit_test_helper.rb +29 -0
- data/test/rails/model.yml +35 -0
- data/test/rails/models/location.rb +4 -0
- data/test/rails/models/note.rb +3 -0
- data/test/rails/models/project.rb +4 -0
- data/test/rails/models/simple_property.rb +2 -0
- data/test/rails/models/task.rb +18 -0
- data/test/rails/models/user.rb +20 -0
- data/test/rails/schema.rb +77 -0
- data/test/rails/test.swf +1 -0
- data/test/rails/test_active_foo.rb +36 -0
- data/test/rails/test_rails_integration_functional.rb +22 -0
- data/test/rails/test_to_fxml.rb +35 -0
- data/test/rails/test_to_json.rb +23 -0
- data/test/rails/views/notes/empty_params_action.html.erb +1 -0
- data/test/rails/views/notes/index.html.erb +1 -0
- metadata +234 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
Description:
|
|
2
|
+
Refreshes main Flex/AIR application file to make sure that
|
|
3
|
+
any of the generated components are included. Warning,
|
|
4
|
+
this will wipe your main application file. Used mostly
|
|
5
|
+
during code generation phase.
|
|
6
|
+
|
|
7
|
+
Examples:
|
|
8
|
+
`./script/generate rx_main_app`
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
class RxMainAppGenerator < RubiGen::Base
|
|
2
|
+
include RestfulX::Configuration
|
|
3
|
+
|
|
4
|
+
attr_reader :project_name,
|
|
5
|
+
:flex_project_name,
|
|
6
|
+
:base_package,
|
|
7
|
+
:base_folder,
|
|
8
|
+
:command_controller_name,
|
|
9
|
+
:model_names,
|
|
10
|
+
:component_names,
|
|
11
|
+
:controller_names,
|
|
12
|
+
:use_air,
|
|
13
|
+
:use_gae,
|
|
14
|
+
:application_tag,
|
|
15
|
+
:flex_root,
|
|
16
|
+
:distributed
|
|
17
|
+
|
|
18
|
+
def initialize(runtime_args, runtime_options = {})
|
|
19
|
+
super
|
|
20
|
+
@project_name, @flex_project_name, @command_controller_name, @base_package, @base_folder,
|
|
21
|
+
@flex_root, @distributed = extract_names
|
|
22
|
+
|
|
23
|
+
project_file_name = APP_ROOT + '/.project'
|
|
24
|
+
if File.exist?(project_file_name)
|
|
25
|
+
@use_air = true if File.read(project_file_name) =~/com.adobe.flexbuilder.apollo.apollobuilder/m
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
if @use_air
|
|
29
|
+
@application_tag = 'WindowedApplication'
|
|
30
|
+
else
|
|
31
|
+
@application_tag = 'Application'
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
@component_names = []
|
|
35
|
+
if File.exists?("#{flex_root}/#{base_folder}/views/generated")
|
|
36
|
+
@component_names = list_mxml_files("#{flex_root}/#{base_folder}/views/generated")
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
@controller_names = []
|
|
40
|
+
if options[:gae] && File.exists?("app/controllers")
|
|
41
|
+
@use_gae = true
|
|
42
|
+
@controller_names =
|
|
43
|
+
Dir.entries("app/controllers").grep(/\.py$/).delete_if { |name| name == "__init__.py" || name == "restful.py" }.map { |name| name.sub(/\.py$/, "") }
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def manifest
|
|
48
|
+
record do |m|
|
|
49
|
+
m.template 'mainapp.mxml', File.join("#{flex_root}", "#{flex_project_name}.mxml")
|
|
50
|
+
if options[:gae]
|
|
51
|
+
m.template 'main.py.erb', 'main.py'
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
protected
|
|
57
|
+
def add_options!(opt)
|
|
58
|
+
opt.separator ''
|
|
59
|
+
opt.separator 'Options:'
|
|
60
|
+
opt.on("--gae", "Generate Google App Engine Python classes in addition to RestfulX Flex resources.",
|
|
61
|
+
"Default: false") { |v| options[:gae] = v }
|
|
62
|
+
opt.on("--distributed", "Creates migrations, controllers and models that use UUIDs and are distribution ready",
|
|
63
|
+
"Default: false") { |v| options[:distributed] = v }
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
import wsgiref.handlers
|
|
5
|
+
|
|
6
|
+
from google.appengine.api import users
|
|
7
|
+
from google.appengine.ext import webapp
|
|
8
|
+
from google.appengine.ext.webapp.util import run_wsgi_app
|
|
9
|
+
from app.controllers import <%= controller_names.join(", ") %>
|
|
10
|
+
|
|
11
|
+
class AppController(webapp.RequestHandler):
|
|
12
|
+
def get(self):
|
|
13
|
+
self.redirect("/public/index.html")
|
|
14
|
+
|
|
15
|
+
def main():
|
|
16
|
+
application = webapp.WSGIApplication(
|
|
17
|
+
[('/*$', AppController),
|
|
18
|
+
<% for component in controller_names -%>
|
|
19
|
+
<% if component == controller_names.last -%>
|
|
20
|
+
('/<%= component %>.*', <%= component %>.Controller)
|
|
21
|
+
<% else -%>
|
|
22
|
+
('/<%= component %>.*', <%= component %>.Controller),
|
|
23
|
+
<% end -%>
|
|
24
|
+
<% end -%>
|
|
25
|
+
], debug=True)
|
|
26
|
+
wsgiref.handlers.CGIHandler().run(application)
|
|
27
|
+
|
|
28
|
+
if __name__ == '__main__':
|
|
29
|
+
main()
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<mx:<%= application_tag %> xmlns:mx="http://www.adobe.com/2006/mxml"
|
|
3
|
+
xmlns:generated="<%= base_package %>.views.generated.*"
|
|
4
|
+
paddingBottom="8" paddingLeft="8" paddingRight="8" paddingTop="8"
|
|
5
|
+
layout="horizontal" styleName="plain" initialize="init()">
|
|
6
|
+
<mx:Script>
|
|
7
|
+
<![CDATA[
|
|
8
|
+
<% if use_air -%>
|
|
9
|
+
<% if distributed -%>
|
|
10
|
+
import air.net.SocketMonitor;
|
|
11
|
+
import org.restfulx.events.PullEndEvent;
|
|
12
|
+
import org.restfulx.events.PullStartEvent;
|
|
13
|
+
import org.restfulx.events.PushEndEvent;
|
|
14
|
+
import org.restfulx.events.PushStartEvent;
|
|
15
|
+
import org.restfulx.controllers.ChangeController;
|
|
16
|
+
import org.restfulx.services.ISyncingServiceProvider;
|
|
17
|
+
<% end -%>
|
|
18
|
+
import org.restfulx.services.air.AIRServiceProvider;
|
|
19
|
+
<% end -%>
|
|
20
|
+
<% if use_gae -%>
|
|
21
|
+
import org.restfulx.services.http.GAEHTTPServiceProvider;
|
|
22
|
+
<% else -%>
|
|
23
|
+
import org.restfulx.services.http.XMLHTTPServiceProvider;
|
|
24
|
+
<% end -%>
|
|
25
|
+
import org.restfulx.Rx;
|
|
26
|
+
import <%= base_package %>.controllers.<%= command_controller_name %>;
|
|
27
|
+
<% if use_air -%>
|
|
28
|
+
<% if distributed -%>
|
|
29
|
+
|
|
30
|
+
[Bindable]
|
|
31
|
+
private var socketMonitor:SocketMonitor;
|
|
32
|
+
|
|
33
|
+
[Bindable]
|
|
34
|
+
private var online:Boolean;
|
|
35
|
+
|
|
36
|
+
[Bindable]
|
|
37
|
+
private var syncStatus:String;
|
|
38
|
+
<% end -%>
|
|
39
|
+
<% end -%>
|
|
40
|
+
|
|
41
|
+
private function init():void {
|
|
42
|
+
<% if use_air -%>
|
|
43
|
+
<% if distributed -%>
|
|
44
|
+
Rx.httpRootUrl = "http://localhost:3000/";
|
|
45
|
+
Rx.enableSync = true;
|
|
46
|
+
|
|
47
|
+
socketMonitor = new SocketMonitor("localhost", 3000);
|
|
48
|
+
socketMonitor.pollInterval = 2000; /* miliseconds */
|
|
49
|
+
socketMonitor.addEventListener(StatusEvent.STATUS, onNetworkStatusChange);
|
|
50
|
+
socketMonitor.start();
|
|
51
|
+
|
|
52
|
+
<% end -%>
|
|
53
|
+
<%= command_controller_name %>.initialize([AIRServiceProvider],
|
|
54
|
+
AIRServiceProvider.ID, "<%= base_package %>");
|
|
55
|
+
<% if distributed -%>
|
|
56
|
+
|
|
57
|
+
<% if use_gae -%>
|
|
58
|
+
Rx.changes.setSyncProviders(
|
|
59
|
+
ISyncingServiceProvider(Rx.services.getServiceProvider(AIRServiceProvider.ID)),
|
|
60
|
+
Rx.services.getServiceProvider(GAEHTTPServiceProvider.ID));
|
|
61
|
+
<% else -%>
|
|
62
|
+
Rx.changes.setSyncProviders(
|
|
63
|
+
ISyncingServiceProvider(Rx.services.getServiceProvider(AIRServiceProvider.ID)),
|
|
64
|
+
Rx.services.getServiceProvider(XMLHTTPServiceProvider.ID));
|
|
65
|
+
<% end -%>
|
|
66
|
+
|
|
67
|
+
Rx.changes.addEventListener(PushStartEvent.ID, onPushStart);
|
|
68
|
+
Rx.changes.addEventListener(PushEndEvent.ID, onPushEnd);
|
|
69
|
+
Rx.changes.addEventListener(PullStartEvent.ID, onPullStart);
|
|
70
|
+
Rx.changes.addEventListener(PullEndEvent.ID, onPullEnd);
|
|
71
|
+
<% end -%>
|
|
72
|
+
<% else -%>
|
|
73
|
+
<% if use_gae -%>
|
|
74
|
+
<%= command_controller_name %>.initialize([GAEHTTPServiceProvider], GAEHTTPServiceProvider.ID);
|
|
75
|
+
<% else -%>
|
|
76
|
+
<%= command_controller_name %>.initialize();
|
|
77
|
+
<% end -%>
|
|
78
|
+
<% end -%>
|
|
79
|
+
}
|
|
80
|
+
<% if use_air -%>
|
|
81
|
+
<% if distributed -%>
|
|
82
|
+
|
|
83
|
+
private function onPushStart(event:Event):void {
|
|
84
|
+
syncStatus = "Pushing changes ...";
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
private function onPushEnd(event:Event):void {
|
|
88
|
+
syncStatus = "Push complete.";
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
private function onPullStart(event:Event):void {
|
|
92
|
+
syncStatus = "Pulling data...";
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
private function onPullEnd(event:Event):void {
|
|
96
|
+
syncStatus = "Pull complete.";
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
private function onNetworkStatusChange(event:StatusEvent):void {
|
|
100
|
+
online = (socketMonitor.available) ? true : false;
|
|
101
|
+
|
|
102
|
+
if (online) {
|
|
103
|
+
<% if use_gae -%>
|
|
104
|
+
Rx.defaultServiceId = GAEHTTPServiceProvider.ID;
|
|
105
|
+
<% else -%>
|
|
106
|
+
Rx.defaultServiceId = XMLHTTPServiceProvider.ID;
|
|
107
|
+
<% end -%>
|
|
108
|
+
} else {
|
|
109
|
+
Rx.defaultServiceId = AIRServiceProvider.ID;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
private function getCurrentProviderName(id:int):String {
|
|
114
|
+
switch (id) {
|
|
115
|
+
<% if use_gae -%>
|
|
116
|
+
case GAEHTTPServiceProvider.ID:
|
|
117
|
+
return "GAE";
|
|
118
|
+
<% else -%>
|
|
119
|
+
case XMLHTTPServiceProvider.ID:
|
|
120
|
+
return "XML/HTTP";
|
|
121
|
+
<% end -%>
|
|
122
|
+
case AIRServiceProvider.ID:
|
|
123
|
+
return "AIR (SQLite)";
|
|
124
|
+
default :
|
|
125
|
+
return "No idea";
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
<% end -%>
|
|
129
|
+
<% end -%>
|
|
130
|
+
]]>
|
|
131
|
+
</mx:Script>
|
|
132
|
+
<% if use_air -%>
|
|
133
|
+
<% if distributed -%>
|
|
134
|
+
<mx:VBox height="100%">
|
|
135
|
+
<mx:Label text="Current Provider: {getCurrentProviderName(Rx.defaultServiceId)}"/>
|
|
136
|
+
<mx:Label text="Status: {online ? 'Online' : 'Offline' }"/>
|
|
137
|
+
<mx:HBox>
|
|
138
|
+
<mx:Button label="Push" click="{Rx.changes.push()}" enabled="{online}"/>
|
|
139
|
+
<mx:Button label="Pull" click="{Rx.changes.pull()}" enabled="{online}"/>
|
|
140
|
+
</mx:HBox>
|
|
141
|
+
<mx:Label text="{syncStatus}"/>
|
|
142
|
+
</mx:VBox>
|
|
143
|
+
<% end -%>
|
|
144
|
+
<% end -%>
|
|
145
|
+
<mx:LinkBar dataProvider="{mainViewStack}" direction="vertical" borderStyle="solid" backgroundColor="#EEEEEE"/>
|
|
146
|
+
<mx:ViewStack id="mainViewStack" width="100%" height="100%">
|
|
147
|
+
<!-- For a simple demo, put all the components here. -->
|
|
148
|
+
<% for component in component_names -%>
|
|
149
|
+
<generated:<%= component %>/>
|
|
150
|
+
<% end -%>
|
|
151
|
+
</mx:ViewStack>
|
|
152
|
+
</mx:<%= application_tag %>>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
Description:
|
|
2
|
+
Scaffolds an entire RestfulX resource. The resource is ready to use as a
|
|
3
|
+
starting point for your restful, resource-oriented application.
|
|
4
|
+
|
|
5
|
+
rx_scaffold :
|
|
6
|
+
1. Generates all required Flex code.
|
|
7
|
+
2. You can pass special belongs_to, has_one and has_many attributes
|
|
8
|
+
to generate appropriate relationships.
|
|
9
|
+
|
|
10
|
+
Pass the name of the model, either CamelCased or under_scored, as the first
|
|
11
|
+
argument, and an optional list of attribute pairs.
|
|
12
|
+
|
|
13
|
+
Attribute pairs are column_name:sql_type arguments specifying the
|
|
14
|
+
model's attributes. Timestamps are added by default, so you don't have to
|
|
15
|
+
specify them by hand as 'created_at:datetime updated_at:datetime'.
|
|
16
|
+
|
|
17
|
+
The syntax for belongs_to, has_one and has_many attributes is as follows:
|
|
18
|
+
belongs_to:<relationship_name> or
|
|
19
|
+
belongs_to:<relationship_name>,<another_relationship>,<and_another>
|
|
20
|
+
|
|
21
|
+
You don't have to think up every attribute up front, but it helps to
|
|
22
|
+
sketch out a few so you can start working with the resource immediately.
|
|
23
|
+
|
|
24
|
+
For example, `rx_scaffold post title:string body:text published:boolean`
|
|
25
|
+
gives you a model with those three attributes.
|
|
26
|
+
|
|
27
|
+
Examples:
|
|
28
|
+
`./script/generate rx_scaffold project name:string has_many:tasks`
|
|
29
|
+
`./script/generate rx_scaffold task name:string belongs_to:project`
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
module RestfulX
|
|
2
|
+
module Generator
|
|
3
|
+
class GeneratedAttribute
|
|
4
|
+
attr_accessor :name, :type, :flex_name
|
|
5
|
+
|
|
6
|
+
def initialize(name, type)
|
|
7
|
+
@name, @type = name, type.to_sym
|
|
8
|
+
@flex_name = name.camelcase(:lower)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def flex_type
|
|
12
|
+
@flex_type = case type
|
|
13
|
+
when :integer then 'int'
|
|
14
|
+
when :date, :datetime, :time then 'Date'
|
|
15
|
+
when :boolean then 'Boolean'
|
|
16
|
+
when :float, :decimal then 'Number'
|
|
17
|
+
else
|
|
18
|
+
'String'
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def flex_default
|
|
23
|
+
@flex_default = case type
|
|
24
|
+
when :integer then '0'
|
|
25
|
+
when :date, :datetime, :time then 'new Date'
|
|
26
|
+
when :boolean then 'false'
|
|
27
|
+
when :float, :decimal then 'new Number'
|
|
28
|
+
else
|
|
29
|
+
"\"\""
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def gae_type
|
|
34
|
+
@gae_type = case type
|
|
35
|
+
when :integer then 'IntegerProperty'
|
|
36
|
+
when :date then 'DateProperty'
|
|
37
|
+
when :time then 'TimeProperty'
|
|
38
|
+
when :datetime then 'DateTimeProperty'
|
|
39
|
+
when :boolean then 'BooleanProperty'
|
|
40
|
+
when :text then 'TextProperty'
|
|
41
|
+
when :float, :decimal then 'FloatProperty'
|
|
42
|
+
else
|
|
43
|
+
'StringProperty'
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def gae_default
|
|
48
|
+
@gae_default = case type
|
|
49
|
+
when :integer then 'default = 0'
|
|
50
|
+
when :date, :time, :datetime then 'auto_now_add = True'
|
|
51
|
+
when :boolean then 'default = False'
|
|
52
|
+
when :float, :decimal then 'default = 0.0'
|
|
53
|
+
else
|
|
54
|
+
""
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
class RxScaffoldGenerator < RubiGen::Base
|
|
62
|
+
include RestfulX::Configuration
|
|
63
|
+
|
|
64
|
+
attr_reader :project_name,
|
|
65
|
+
:flex_project_name,
|
|
66
|
+
:base_package,
|
|
67
|
+
:base_folder,
|
|
68
|
+
:command_controller_name,
|
|
69
|
+
:flex_root
|
|
70
|
+
|
|
71
|
+
attr_reader :belongs_tos,
|
|
72
|
+
:has_manies,
|
|
73
|
+
:has_ones,
|
|
74
|
+
:attachment_field,
|
|
75
|
+
:has_many_through,
|
|
76
|
+
:polymorphic,
|
|
77
|
+
:tree_model,
|
|
78
|
+
:layout,
|
|
79
|
+
:ignored_fields,
|
|
80
|
+
:args_for_generation
|
|
81
|
+
|
|
82
|
+
attr_reader :name,
|
|
83
|
+
:class_name,
|
|
84
|
+
:file_name
|
|
85
|
+
|
|
86
|
+
def initialize(runtime_args, runtime_options = {})
|
|
87
|
+
super
|
|
88
|
+
|
|
89
|
+
# Name argument is required.
|
|
90
|
+
usage if runtime_args.empty?
|
|
91
|
+
|
|
92
|
+
@args = runtime_args.dup
|
|
93
|
+
@name = @args.shift
|
|
94
|
+
@file_name = @name.underscore
|
|
95
|
+
@class_name = @name.camelize
|
|
96
|
+
|
|
97
|
+
@project_name, @flex_project_name, @command_controller_name,
|
|
98
|
+
@base_package, @base_folder, @flex_root = extract_names
|
|
99
|
+
extract_relationships
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def manifest
|
|
103
|
+
record do |m|
|
|
104
|
+
m.template 'model.as.erb',
|
|
105
|
+
File.join("#{flex_root}", base_folder, "models", "#{@class_name}.as"),
|
|
106
|
+
:assigns => { :resource_controller_name => "#{file_name.pluralize}" }
|
|
107
|
+
|
|
108
|
+
if @layout.size > 0
|
|
109
|
+
m.template "layouts/#{@layout}.erb",
|
|
110
|
+
File.join("#{@flex_root}", base_folder, "views", "generated", "#{@class_name}Box.mxml"),
|
|
111
|
+
:assigns => { :resource_controller_name => "#{file_name.pluralize}" }
|
|
112
|
+
else
|
|
113
|
+
m.template "layouts/#{RxSettings.layouts.default}.erb",
|
|
114
|
+
File.join("#{@flex_root}", base_folder, "views", "generated", "#{@class_name}Box.mxml"),
|
|
115
|
+
:assigns => { :resource_controller_name => "#{file_name.pluralize}" }
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
if options[:gae]
|
|
119
|
+
m.template 'controller.py.erb', "app/controllers/#{file_name.pluralize}.py"
|
|
120
|
+
m.template 'model.py.erb', "app/models/#{file_name}.py"
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
m.dependency 'rx_controller', [name] + @args, :collision => :force, :gae => options[:gae]
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
protected
|
|
128
|
+
def extract_relationships
|
|
129
|
+
# arrays
|
|
130
|
+
@belongs_tos = []
|
|
131
|
+
@has_ones = []
|
|
132
|
+
@has_manies = []
|
|
133
|
+
@attachment_field = []
|
|
134
|
+
@polymorphic = []
|
|
135
|
+
@tree_model = []
|
|
136
|
+
@layout = []
|
|
137
|
+
@ignored_fields = []
|
|
138
|
+
|
|
139
|
+
# hashes
|
|
140
|
+
@has_many_through = {}
|
|
141
|
+
|
|
142
|
+
@args.each do |arg|
|
|
143
|
+
# arrays
|
|
144
|
+
if arg =~ /^has_one:/
|
|
145
|
+
@has_ones = arg.split(':')[1].split(',')
|
|
146
|
+
elsif arg =~ /^has_many:/
|
|
147
|
+
@has_manies = arg.split(":")[1].split(",")
|
|
148
|
+
elsif arg =~ /^belongs_to:/
|
|
149
|
+
@belongs_tos = arg.split(":")[1].split(',')
|
|
150
|
+
elsif arg =~ /^attachment_field:/
|
|
151
|
+
@attachment_field = arg.split(":")[1].split(',')
|
|
152
|
+
elsif arg =~ /^polymorphic:/
|
|
153
|
+
@polymorphic = arg.split(":")[1].split(',')
|
|
154
|
+
elsif arg =~ /^tree_model:/
|
|
155
|
+
@tree_model = arg.split(":")[1].split(',')
|
|
156
|
+
elsif arg =~ /^layout:/
|
|
157
|
+
@layout = arg.split(":")[1].split(',')
|
|
158
|
+
elsif arg =~ /^ignored_fields:/
|
|
159
|
+
@ignored_fields = arg.split(":")[1].split(',')
|
|
160
|
+
# hashes
|
|
161
|
+
elsif arg =~ /^has_many_through:/
|
|
162
|
+
hmt_arr = arg.split(":")[1].split(',')
|
|
163
|
+
@has_many_through[hmt_arr.first] = hmt_arr.last
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
# delete special fields from @args ivar
|
|
168
|
+
%w(has_one has_many belongs_to attachment_field has_many_through
|
|
169
|
+
polymorphic tree_model layout ignored_fields).each do |special_field|
|
|
170
|
+
@args.delete_if { |f| f =~ /^(#{special_field}):/ }
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
@args_for_generation = @args.clone
|
|
174
|
+
|
|
175
|
+
# delete ignored_fields from @args ivar
|
|
176
|
+
@ignored_fields.each do |ignored|
|
|
177
|
+
@args.delete_if { |f| f =~ /^(#{ignored}):/ }
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def attributes
|
|
183
|
+
@attributes ||= @args.collect do |attribute|
|
|
184
|
+
RestfulX::Generator::GeneratedAttribute.new(*attribute.split(":"))
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def add_options!(opt)
|
|
189
|
+
opt.separator ''
|
|
190
|
+
opt.separator 'Options:'
|
|
191
|
+
opt.on("--gae", "Generate Google App Engine Python classes in addition to RestfulX Flex resources.",
|
|
192
|
+
"Default: false") { |v| options[:gae] = v }
|
|
193
|
+
end
|
|
194
|
+
end
|