mta_json 0.0.1

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 (79) hide show
  1. data/.gitignore +17 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE.txt +22 -0
  4. data/README.md +130 -0
  5. data/Rakefile +1 -0
  6. data/examples/crud/README.md +40 -0
  7. data/examples/crud/crud.lua +113 -0
  8. data/examples/crud/meta.xml +14 -0
  9. data/examples/crud/mta/crud/crud.lua +0 -0
  10. data/examples/crud/mta/crud/meta.xml +3 -0
  11. data/examples/crud/rails/.gitignore +15 -0
  12. data/examples/crud/rails/Gemfile +40 -0
  13. data/examples/crud/rails/Rakefile +7 -0
  14. data/examples/crud/rails/app/assets/images/rails.png +0 -0
  15. data/examples/crud/rails/app/assets/javascripts/application.js +15 -0
  16. data/examples/crud/rails/app/assets/javascripts/posts.js.coffee +3 -0
  17. data/examples/crud/rails/app/assets/stylesheets/application.css +13 -0
  18. data/examples/crud/rails/app/assets/stylesheets/posts.css.scss +3 -0
  19. data/examples/crud/rails/app/assets/stylesheets/scaffolds.css.scss +69 -0
  20. data/examples/crud/rails/app/controllers/application_controller.rb +3 -0
  21. data/examples/crud/rails/app/controllers/posts_controller.rb +83 -0
  22. data/examples/crud/rails/app/helpers/application_helper.rb +2 -0
  23. data/examples/crud/rails/app/helpers/posts_helper.rb +2 -0
  24. data/examples/crud/rails/app/mailers/.gitkeep +0 -0
  25. data/examples/crud/rails/app/models/.gitkeep +0 -0
  26. data/examples/crud/rails/app/models/post.rb +3 -0
  27. data/examples/crud/rails/app/views/layouts/application.html.erb +14 -0
  28. data/examples/crud/rails/app/views/posts/_form.html.erb +25 -0
  29. data/examples/crud/rails/app/views/posts/edit.html.erb +6 -0
  30. data/examples/crud/rails/app/views/posts/index.html.erb +25 -0
  31. data/examples/crud/rails/app/views/posts/new.html.erb +5 -0
  32. data/examples/crud/rails/app/views/posts/show.html.erb +15 -0
  33. data/examples/crud/rails/config/application.rb +64 -0
  34. data/examples/crud/rails/config/boot.rb +6 -0
  35. data/examples/crud/rails/config/database.yml +25 -0
  36. data/examples/crud/rails/config/environment.rb +5 -0
  37. data/examples/crud/rails/config/environments/development.rb +37 -0
  38. data/examples/crud/rails/config/environments/production.rb +67 -0
  39. data/examples/crud/rails/config/environments/test.rb +37 -0
  40. data/examples/crud/rails/config/initializers/backtrace_silencers.rb +7 -0
  41. data/examples/crud/rails/config/initializers/inflections.rb +15 -0
  42. data/examples/crud/rails/config/initializers/mime_types.rb +5 -0
  43. data/examples/crud/rails/config/initializers/secret_token.rb +7 -0
  44. data/examples/crud/rails/config/initializers/session_store.rb +8 -0
  45. data/examples/crud/rails/config/initializers/wrap_parameters.rb +14 -0
  46. data/examples/crud/rails/config/locales/en.yml +5 -0
  47. data/examples/crud/rails/config/routes.rb +61 -0
  48. data/examples/crud/rails/config.ru +4 -0
  49. data/examples/crud/rails/db/migrate/20130320115007_create_posts.rb +10 -0
  50. data/examples/crud/rails/db/schema.rb +23 -0
  51. data/examples/crud/rails/db/seeds.rb +7 -0
  52. data/examples/crud/rails/lib/assets/.gitkeep +0 -0
  53. data/examples/crud/rails/lib/tasks/.gitkeep +0 -0
  54. data/examples/crud/rails/log/.gitkeep +0 -0
  55. data/examples/crud/rails/public/404.html +26 -0
  56. data/examples/crud/rails/public/422.html +26 -0
  57. data/examples/crud/rails/public/500.html +25 -0
  58. data/examples/crud/rails/public/favicon.ico +0 -0
  59. data/examples/crud/rails/public/index.html +241 -0
  60. data/examples/crud/rails/public/robots.txt +5 -0
  61. data/examples/crud/rails/script/rails +6 -0
  62. data/examples/crud/rails/test/fixtures/.gitkeep +0 -0
  63. data/examples/crud/rails/test/fixtures/posts.yml +9 -0
  64. data/examples/crud/rails/test/functional/.gitkeep +0 -0
  65. data/examples/crud/rails/test/functional/posts_controller_test.rb +49 -0
  66. data/examples/crud/rails/test/integration/.gitkeep +0 -0
  67. data/examples/crud/rails/test/performance/browsing_test.rb +12 -0
  68. data/examples/crud/rails/test/test_helper.rb +13 -0
  69. data/examples/crud/rails/test/unit/.gitkeep +0 -0
  70. data/examples/crud/rails/test/unit/helpers/posts_helper_test.rb +4 -0
  71. data/examples/crud/rails/test/unit/post_test.rb +7 -0
  72. data/examples/crud/rails/vendor/assets/javascripts/.gitkeep +0 -0
  73. data/examples/crud/rails/vendor/assets/stylesheets/.gitkeep +0 -0
  74. data/examples/crud/rails/vendor/plugins/.gitkeep +0 -0
  75. data/lib/mta_json/version.rb +3 -0
  76. data/lib/mta_json/wrapper.rb +120 -0
  77. data/lib/mta_json.rb +6 -0
  78. data/mta_json.gemspec +23 -0
  79. metadata +226 -0
@@ -0,0 +1,241 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Ruby on Rails: Welcome aboard</title>
5
+ <style type="text/css" media="screen">
6
+ body {
7
+ margin: 0;
8
+ margin-bottom: 25px;
9
+ padding: 0;
10
+ background-color: #f0f0f0;
11
+ font-family: "Lucida Grande", "Bitstream Vera Sans", "Verdana";
12
+ font-size: 13px;
13
+ color: #333;
14
+ }
15
+
16
+ h1 {
17
+ font-size: 28px;
18
+ color: #000;
19
+ }
20
+
21
+ a {color: #03c}
22
+ a:hover {
23
+ background-color: #03c;
24
+ color: white;
25
+ text-decoration: none;
26
+ }
27
+
28
+
29
+ #page {
30
+ background-color: #f0f0f0;
31
+ width: 750px;
32
+ margin: 0;
33
+ margin-left: auto;
34
+ margin-right: auto;
35
+ }
36
+
37
+ #content {
38
+ float: left;
39
+ background-color: white;
40
+ border: 3px solid #aaa;
41
+ border-top: none;
42
+ padding: 25px;
43
+ width: 500px;
44
+ }
45
+
46
+ #sidebar {
47
+ float: right;
48
+ width: 175px;
49
+ }
50
+
51
+ #footer {
52
+ clear: both;
53
+ }
54
+
55
+ #header, #about, #getting-started {
56
+ padding-left: 75px;
57
+ padding-right: 30px;
58
+ }
59
+
60
+
61
+ #header {
62
+ background-image: url("assets/rails.png");
63
+ background-repeat: no-repeat;
64
+ background-position: top left;
65
+ height: 64px;
66
+ }
67
+ #header h1, #header h2 {margin: 0}
68
+ #header h2 {
69
+ color: #888;
70
+ font-weight: normal;
71
+ font-size: 16px;
72
+ }
73
+
74
+
75
+ #about h3 {
76
+ margin: 0;
77
+ margin-bottom: 10px;
78
+ font-size: 14px;
79
+ }
80
+
81
+ #about-content {
82
+ background-color: #ffd;
83
+ border: 1px solid #fc0;
84
+ margin-left: -55px;
85
+ margin-right: -10px;
86
+ }
87
+ #about-content table {
88
+ margin-top: 10px;
89
+ margin-bottom: 10px;
90
+ font-size: 11px;
91
+ border-collapse: collapse;
92
+ }
93
+ #about-content td {
94
+ padding: 10px;
95
+ padding-top: 3px;
96
+ padding-bottom: 3px;
97
+ }
98
+ #about-content td.name {color: #555}
99
+ #about-content td.value {color: #000}
100
+
101
+ #about-content ul {
102
+ padding: 0;
103
+ list-style-type: none;
104
+ }
105
+
106
+ #about-content.failure {
107
+ background-color: #fcc;
108
+ border: 1px solid #f00;
109
+ }
110
+ #about-content.failure p {
111
+ margin: 0;
112
+ padding: 10px;
113
+ }
114
+
115
+
116
+ #getting-started {
117
+ border-top: 1px solid #ccc;
118
+ margin-top: 25px;
119
+ padding-top: 15px;
120
+ }
121
+ #getting-started h1 {
122
+ margin: 0;
123
+ font-size: 20px;
124
+ }
125
+ #getting-started h2 {
126
+ margin: 0;
127
+ font-size: 14px;
128
+ font-weight: normal;
129
+ color: #333;
130
+ margin-bottom: 25px;
131
+ }
132
+ #getting-started ol {
133
+ margin-left: 0;
134
+ padding-left: 0;
135
+ }
136
+ #getting-started li {
137
+ font-size: 18px;
138
+ color: #888;
139
+ margin-bottom: 25px;
140
+ }
141
+ #getting-started li h2 {
142
+ margin: 0;
143
+ font-weight: normal;
144
+ font-size: 18px;
145
+ color: #333;
146
+ }
147
+ #getting-started li p {
148
+ color: #555;
149
+ font-size: 13px;
150
+ }
151
+
152
+
153
+ #sidebar ul {
154
+ margin-left: 0;
155
+ padding-left: 0;
156
+ }
157
+ #sidebar ul h3 {
158
+ margin-top: 25px;
159
+ font-size: 16px;
160
+ padding-bottom: 10px;
161
+ border-bottom: 1px solid #ccc;
162
+ }
163
+ #sidebar li {
164
+ list-style-type: none;
165
+ }
166
+ #sidebar ul.links li {
167
+ margin-bottom: 5px;
168
+ }
169
+
170
+ .filename {
171
+ font-style: italic;
172
+ }
173
+ </style>
174
+ <script type="text/javascript">
175
+ function about() {
176
+ info = document.getElementById('about-content');
177
+ if (window.XMLHttpRequest)
178
+ { xhr = new XMLHttpRequest(); }
179
+ else
180
+ { xhr = new ActiveXObject("Microsoft.XMLHTTP"); }
181
+ xhr.open("GET","rails/info/properties",false);
182
+ xhr.send("");
183
+ info.innerHTML = xhr.responseText;
184
+ info.style.display = 'block'
185
+ }
186
+ </script>
187
+ </head>
188
+ <body>
189
+ <div id="page">
190
+ <div id="sidebar">
191
+ <ul id="sidebar-items">
192
+ <li>
193
+ <h3>Browse the documentation</h3>
194
+ <ul class="links">
195
+ <li><a href="http://guides.rubyonrails.org/">Rails Guides</a></li>
196
+ <li><a href="http://api.rubyonrails.org/">Rails API</a></li>
197
+ <li><a href="http://www.ruby-doc.org/core/">Ruby core</a></li>
198
+ <li><a href="http://www.ruby-doc.org/stdlib/">Ruby standard library</a></li>
199
+ </ul>
200
+ </li>
201
+ </ul>
202
+ </div>
203
+
204
+ <div id="content">
205
+ <div id="header">
206
+ <h1>Welcome aboard</h1>
207
+ <h2>You&rsquo;re riding Ruby on Rails!</h2>
208
+ </div>
209
+
210
+ <div id="about">
211
+ <h3><a href="rails/info/properties" onclick="about(); return false">About your application&rsquo;s environment</a></h3>
212
+ <div id="about-content" style="display: none"></div>
213
+ </div>
214
+
215
+ <div id="getting-started">
216
+ <h1>Getting started</h1>
217
+ <h2>Here&rsquo;s how to get rolling:</h2>
218
+
219
+ <ol>
220
+ <li>
221
+ <h2>Use <code>rails generate</code> to create your models and controllers</h2>
222
+ <p>To see all available options, run it without parameters.</p>
223
+ </li>
224
+
225
+ <li>
226
+ <h2>Set up a default route and remove <span class="filename">public/index.html</span></h2>
227
+ <p>Routes are set up in <span class="filename">config/routes.rb</span>.</p>
228
+ </li>
229
+
230
+ <li>
231
+ <h2>Create your database</h2>
232
+ <p>Run <code>rake db:create</code> to create your database. If you're not using SQLite (the default), edit <span class="filename">config/database.yml</span> with your username and password.</p>
233
+ </li>
234
+ </ol>
235
+ </div>
236
+ </div>
237
+
238
+ <div id="footer">&nbsp;</div>
239
+ </div>
240
+ </body>
241
+ </html>
@@ -0,0 +1,5 @@
1
+ # See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file
2
+ #
3
+ # To ban all spiders from the entire site uncomment the next two lines:
4
+ # User-Agent: *
5
+ # Disallow: /
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby.exe
2
+ # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
3
+
4
+ APP_PATH = File.expand_path('../../config/application', __FILE__)
5
+ require File.expand_path('../../config/boot', __FILE__)
6
+ require 'rails/commands'
File without changes
@@ -0,0 +1,9 @@
1
+ # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html
2
+
3
+ one:
4
+ title: MyString
5
+ text: MyText
6
+
7
+ two:
8
+ title: MyString
9
+ text: MyText
File without changes
@@ -0,0 +1,49 @@
1
+ require 'test_helper'
2
+
3
+ class PostsControllerTest < ActionController::TestCase
4
+ setup do
5
+ @post = posts(:one)
6
+ end
7
+
8
+ test "should get index" do
9
+ get :index
10
+ assert_response :success
11
+ assert_not_nil assigns(:posts)
12
+ end
13
+
14
+ test "should get new" do
15
+ get :new
16
+ assert_response :success
17
+ end
18
+
19
+ test "should create post" do
20
+ assert_difference('Post.count') do
21
+ post :create, post: { text: @post.text, title: @post.title }
22
+ end
23
+
24
+ assert_redirected_to post_path(assigns(:post))
25
+ end
26
+
27
+ test "should show post" do
28
+ get :show, id: @post
29
+ assert_response :success
30
+ end
31
+
32
+ test "should get edit" do
33
+ get :edit, id: @post
34
+ assert_response :success
35
+ end
36
+
37
+ test "should update post" do
38
+ put :update, id: @post, post: { text: @post.text, title: @post.title }
39
+ assert_redirected_to post_path(assigns(:post))
40
+ end
41
+
42
+ test "should destroy post" do
43
+ assert_difference('Post.count', -1) do
44
+ delete :destroy, id: @post
45
+ end
46
+
47
+ assert_redirected_to posts_path
48
+ end
49
+ end
File without changes
@@ -0,0 +1,12 @@
1
+ require 'test_helper'
2
+ require 'rails/performance_test_help'
3
+
4
+ class BrowsingTest < ActionDispatch::PerformanceTest
5
+ # Refer to the documentation for all available options
6
+ # self.profile_options = { :runs => 5, :metrics => [:wall_time, :memory]
7
+ # :output => 'tmp/performance', :formats => [:flat] }
8
+
9
+ def test_homepage
10
+ get '/'
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ ENV["RAILS_ENV"] = "test"
2
+ require File.expand_path('../../config/environment', __FILE__)
3
+ require 'rails/test_help'
4
+
5
+ class ActiveSupport::TestCase
6
+ # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
7
+ #
8
+ # Note: You'll currently still have to declare fixtures explicitly in integration tests
9
+ # -- they do not yet inherit this setting
10
+ fixtures :all
11
+
12
+ # Add more helper methods to be used by all tests here...
13
+ end
File without changes
@@ -0,0 +1,4 @@
1
+ require 'test_helper'
2
+
3
+ class PostsHelperTest < ActionView::TestCase
4
+ end
@@ -0,0 +1,7 @@
1
+ require 'test_helper'
2
+
3
+ class PostTest < ActiveSupport::TestCase
4
+ # test "the truth" do
5
+ # assert true
6
+ # end
7
+ end
File without changes
@@ -0,0 +1,3 @@
1
+ module MtaJson
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,120 @@
1
+ module MtaJson
2
+ # wraps calls to .mta-urls in a MTA-specific format.
3
+ # The main difference is:
4
+ # * the request body needs to have the surrounding [ ] removed (which technically represents a JSON-Array)
5
+ # * the response body needs [ ] added (again, a JSON-Array) which consists of:
6
+ # * body of the response
7
+ # * headers
8
+ # MTA technically allows multiple parameters, but that doesn't really suit rails' named parameters (param[:cake]).
9
+ class Wrapper
10
+ # env[...]
11
+ CONTENT_TYPE = 'CONTENT_TYPE'.freeze
12
+ BODY = 'rack.input'.freeze
13
+ FORM_INPUT = 'rack.request.form_input'.freeze
14
+ FORM_HASH = 'rack.request.form_hash'.freeze
15
+ METHOD = 'REQUEST_METHOD'.freeze
16
+ POST = 'POST'.freeze
17
+ PATH_INFO = 'PATH_INFO'.freeze
18
+
19
+ # HTTP-Response-Headers
20
+ CONTENT_LENGTH = 'Content-Length'.freeze
21
+
22
+ # Allowed Methods to be set by MTA
23
+ ALLOWED_METHODS = %w(POST GET PUT DELETE)
24
+
25
+ def initialize app
26
+ @app = app
27
+ end
28
+
29
+ # callRemote on the MTA-side may have [0, 1 or 2] parameter(s):
30
+ # * if no parameters, params[...] is empty within rails
31
+ # * first parameter - as a table - fills the params[...] hash which is accessible in controllers (etc)
32
+ # i.e.
33
+ # callRemote("http://localhost/auth.mta", function, { name = 'a', password = 'b' })
34
+ # makes the following parameters available in the called controller
35
+ # params[:name] = 'a'
36
+ # params[:password] = 'b'
37
+ # * second parameter - as a table - options on how the request is handled. See update_options for details,
38
+ # for example { 'method' = 'GET' } allows GET-Requests, while usually callRemote does only POST-Requests.
39
+ #
40
+ # This is unlike the PHP-SDK, which may have multiple parameters and allows access via numbers
41
+ # $input = mta::getInput();
42
+ # $name = $input[0];
43
+ # $password = $input[1];
44
+ # Rails has named parameters, so there's no explicit support for them numbers.
45
+ #
46
+ # callRemote for MTA should always call files ending with .mta, for example:
47
+ # * /auth => /auth.mta
48
+ #
49
+ # This will call the related JSON-Methods, i.e.
50
+ # respond_to do |format|
51
+ # format.html { ... } # certainly not this
52
+ # format.json { render :json => @object } # this gets called!
53
+ # end
54
+ #
55
+ # There is no support for elements and/or resources (yet?).
56
+ def call env
57
+ path = env[PATH_INFO]
58
+ if path.end_with?('.mta') and (body = env[BODY].read).length != 0 and env[METHOD] == POST
59
+ # replace ".mta" with ".json"
60
+ env[PATH_INFO] = path[0..-5] + '.json'
61
+
62
+ json = JSON.parse body
63
+ raise Exception, "Number of JSON elements > 2: actual #{json.size}" if json.size > 2
64
+
65
+ # optional options!
66
+ update_options env, json[1].with_indifferent_access if json.size >= 2
67
+
68
+ # any parameters given? otherwise we don't really care for any params
69
+ update_params env, json[0] if json.size >= 1 and json[0] != 0 # 0 is nil in terms of callRemote. JSON has 'null' though!
70
+
71
+ # call the other middlewares
72
+ status, headers, response = @app.call(env)
73
+
74
+ # alter only successful status codes to be more mta-ish
75
+ if (200..299).include?(status)
76
+ # mta /can/ handle multiple parameters as response.
77
+ # We do not want and/or need this, but merely wrap the response body in square brackets as to return a single element
78
+ # If render :json => @obj is used in the controller, this should make exactly @obj available in MTA.
79
+ response = to_response(response, headers)
80
+
81
+ # overwrite the length if already set
82
+ if headers['Content-Length']
83
+ headers['Content-Length'] = response.length
84
+ end
85
+ end
86
+
87
+ return [status, headers, response]
88
+ else
89
+ # normal call, nevermind that whole mta business
90
+ @app.call(env)
91
+ end
92
+ end
93
+
94
+ # update all of the parameter-related values in the current request's environment
95
+ def update_params env, json
96
+ env[FORM_HASH] = json
97
+ env[BODY] = StringIO.new(Rack::Utils.build_query(json))
98
+ env[FORM_INPUT] = env[BODY]
99
+ end
100
+
101
+ # updates the options
102
+ def update_options env, options
103
+ # switch between POST and GET?
104
+ if ALLOWED_METHODS.include?(options[:method])
105
+ # (possibly) TODO - pass parameters for GET instead of POST in update_params then?
106
+ # see https://github.com/rack/rack/blob/master/lib/rack/request.rb -> def GET
107
+ env[METHOD] = options[:method]
108
+ end
109
+ end
110
+
111
+ # returns the response body: old response body + headers as a JSON array
112
+ def to_response response, headers
113
+ body = ""
114
+ response.each do |s|
115
+ body << s.to_s
116
+ end
117
+ ["[#{body},#{headers.to_json.to_s}]"]
118
+ end
119
+ end
120
+ end
data/lib/mta_json.rb ADDED
@@ -0,0 +1,6 @@
1
+ require "mta_json/version"
2
+ require "mta_json/wrapper"
3
+
4
+ module MtaJson
5
+
6
+ end
data/mta_json.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'mta_json/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "mta_json"
8
+ spec.version = MtaJson::VERSION
9
+ spec.authors = ["Marcus Bauer"]
10
+ spec.email = ["mabako@gmail.com"]
11
+ spec.description = "Wraps MTA:SA's JSON format to support named parameters and different HTTP Methods with callRemote"
12
+ spec.summary = "Wrapper for MTA:SA's JSON format"
13
+ spec.homepage = "https://github.com/mabako/mta_json"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features|examples)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ end