apipie-rails 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. data/.travis.yml +1 -2
  2. data/CHANGELOG.md +26 -0
  3. data/README.rst +94 -3
  4. data/app/controllers/apipie/apipies_controller.rb +28 -10
  5. data/app/views/apipie/apipies/_disqus.html.erb +4 -2
  6. data/app/views/apipie/apipies/_languages.erb +6 -0
  7. data/app/views/apipie/apipies/_method_detail.erb +7 -7
  8. data/app/views/apipie/apipies/_params.html.erb +2 -2
  9. data/app/views/apipie/apipies/_params_plain.html.erb +2 -2
  10. data/app/views/apipie/apipies/apipie_404.html.erb +7 -4
  11. data/app/views/apipie/apipies/getting_started.html.erb +5 -3
  12. data/app/views/apipie/apipies/index.html.erb +7 -6
  13. data/app/views/apipie/apipies/method.html.erb +4 -2
  14. data/app/views/apipie/apipies/plain.html.erb +3 -3
  15. data/app/views/apipie/apipies/resource.html.erb +3 -2
  16. data/app/views/apipie/apipies/static.html.erb +7 -7
  17. data/app/views/layouts/apipie/apipie.html.erb +1 -1
  18. data/config/locales/en.yml +27 -0
  19. data/lib/apipie-rails.rb +7 -0
  20. data/lib/apipie/apipie_module.rb +5 -2
  21. data/lib/apipie/application.rb +27 -16
  22. data/lib/apipie/configuration.rb +6 -1
  23. data/lib/apipie/extractor.rb +35 -26
  24. data/lib/apipie/extractor/recorder.rb +9 -5
  25. data/lib/apipie/extractor/writer.rb +36 -7
  26. data/lib/apipie/method_description.rb +6 -6
  27. data/lib/apipie/param_description.rb +9 -4
  28. data/lib/apipie/resource_description.rb +5 -5
  29. data/lib/apipie/routing.rb +1 -1
  30. data/lib/apipie/version.rb +1 -1
  31. data/lib/generators/apipie/install/templates/initializer.rb.erb +1 -1
  32. data/lib/tasks/apipie.rake +89 -47
  33. data/spec/dummy/doc/apipie_examples.json +1 -0
  34. data/spec/lib/extractor/middleware_spec.rb +21 -0
  35. data/spec/lib/extractor/writer_spec.rb +76 -0
  36. metadata +10 -5
  37. data/Gemfile.rails30 +0 -5
  38. data/spec/dummy/doc/apipie_examples.yml +0 -28
@@ -7,6 +7,7 @@
7
7
  <%= @resource[:name] %>
8
8
  <% if @resource[:version] %><% end %>
9
9
  </li>
10
+ <%= render(:partial => "languages", :locals => {:doc_url => @resource[:doc_url]}) %>
10
11
  </ul>
11
12
 
12
13
  <div class='page-header'>
@@ -62,6 +63,6 @@
62
63
  <% end %>
63
64
  </div>
64
65
 
65
- <% content_for :apipie_footer do %>
66
- <%= raw @doc[:copyright] %>
66
+ <% unless content_for(:apipie_footer) == @doc[:copyright] %>
67
+ <%= content_for :apipie_footer, raw(@doc[:copyright]) %>
67
68
  <% end %>
@@ -62,14 +62,14 @@
62
62
  <div>
63
63
  <%= raw method[:full_description] %>
64
64
  <% unless method[:examples].blank? %>
65
- <h2>Examples</h2>
65
+ <h2><%= t('apipie.examples') %></h2>
66
66
  <% method[:examples].each do |example| %>
67
67
  <pre><%= example %></pre>
68
68
  <% end %>
69
69
  <% end %>
70
70
 
71
71
  <% unless method[:errors].blank? %>
72
- <h2>Errors</h2>
72
+ <h2><%= t('apipie.errors') %></h2>
73
73
  <% method[:errors].each do |err| %>
74
74
  <%= err[:code] %>
75
75
  <%= err[:description] %>
@@ -79,12 +79,12 @@
79
79
  <% end %>
80
80
 
81
81
  <% unless method[:params].blank? %>
82
- <h2>Params</h2>
82
+ <h2><%= t('apipie.params') %></h2>
83
83
  <table class='table'>
84
84
  <thead>
85
85
  <tr>
86
- <th>Param name</th>
87
- <th>Description</th>
86
+ <th><%= t('apipie.param_name') %></th>
87
+ <th><%= t('apipie.description') %></th>
88
88
  </tr>
89
89
  </thead>
90
90
  <tbody>
@@ -97,6 +97,6 @@
97
97
  </div>
98
98
  <% end %>
99
99
 
100
- <% content_for :apipie_footer do %>
101
- <%= raw @doc[:copyright] %>
100
+ <% unless content_for(:apipie_footer) == @doc[:copyright] %>
101
+ <%= content_for :apipie_footer, raw(@doc[:copyright]) %>
102
102
  <% end %>
@@ -1,7 +1,7 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
- <title>API documentation</title>
4
+ <title><%= t('apipie.api_documentation') %></title>
5
5
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
6
6
  <%= Apipie.include_stylesheets %>
7
7
  <link type='text/css' rel='stylesheet' href='<%= Apipie.full_url("stylesheets/application.css")%>'/>
@@ -0,0 +1,27 @@
1
+ en:
2
+ apipie:
3
+ resources: Resources
4
+ resource: Resource
5
+ description: Description
6
+ no_docs_found: No documentation found
7
+ no_docs_found_descr: We have not found any documentation for your API.
8
+ follow_instructions_html: Follow %{href} on how to describe your controllers.
9
+ follow_instructions_href: further instructions
10
+ oops: Oops!!
11
+ resource_not_found_html: Resource %{res} not found.
12
+ method_not_found_html: Method %{method} not found for resource %{resource}.
13
+ goto_homepage_html: Try going to %{href}
14
+ goto_homepage_href: "%{app_name} API documentation homepage"
15
+ required: required
16
+ optional: optional
17
+ nil_allowed: nil allowed
18
+ param_name: Param name
19
+ params: Params
20
+ examples: Examples
21
+ metadata: Metadata
22
+ errors: Errors
23
+ supported_formats: Supported Formats
24
+ enable_javascript_html: Please enable JavaScript to view the %{comments_href}.
25
+ comments_powered_by_disqus: comments powered by %{disqus}
26
+ api_documentation: API documentation
27
+
data/lib/apipie-rails.rb CHANGED
@@ -1,3 +1,6 @@
1
+ require 'i18n'
2
+ require 'active_support/hash_with_indifferent_access'
3
+
1
4
  require "apipie/routing"
2
5
  require "apipie/markup"
3
6
  require "apipie/apipie_module"
@@ -13,3 +16,7 @@ require "apipie/validator"
13
16
  require "apipie/railtie"
14
17
  require 'apipie/extractor'
15
18
  require "apipie/version"
19
+
20
+ if Rails.version.start_with?("3.0")
21
+ warn 'Warning: apipie-rails is not going to support Rails 3.0 anymore in future versions'
22
+ end
@@ -8,9 +8,9 @@ module Apipie
8
8
  @application ||= Apipie::Application.new
9
9
  end
10
10
 
11
- def self.to_json(version = nil, resource_name = nil, method_name = nil)
11
+ def self.to_json(version = nil, resource_name = nil, method_name = nil, lang = nil)
12
12
  version ||= Apipie.configuration.default_version
13
- app.to_json(version, resource_name, method_name)
13
+ app.to_json(version, resource_name, method_name, lang)
14
14
  end
15
15
 
16
16
  # all calls delegated to Apipie::Application instance
@@ -59,4 +59,7 @@ module Apipie
59
59
  version && self.configuration.api_base_url.has_key?(version)
60
60
  end
61
61
 
62
+ def self.record(record)
63
+ Apipie::Extractor.start record
64
+ end
62
65
  end
@@ -207,25 +207,14 @@ module Apipie
207
207
 
208
208
  def recorded_examples
209
209
  return @recorded_examples if @recorded_examples
210
- tape_file = File.join(Rails.root,"doc","apipie_examples.yml")
211
- if File.exists?(tape_file)
212
- #if SafeYAML gem is enabled, it will load examples as an array of Hash, instead of hash
213
- if YAML.respond_to?(:safe_load_file) && defined?(SafeYAML)
214
- @recorded_examples = YAML.load_file(tape_file, :safe=>false)
215
- else
216
- @recorded_examples = YAML.load_file(tape_file)
217
- end
218
- else
219
- @recorded_examples = {}
220
- end
221
- @recorded_examples
210
+ @recorded_examples = Apipie::Extractor::Writer.load_recorded_examples
222
211
  end
223
212
 
224
213
  def reload_examples
225
214
  @recorded_examples = nil
226
215
  end
227
216
 
228
- def to_json(version, resource_name, method_name)
217
+ def to_json(version, resource_name, method_name, lang)
229
218
 
230
219
  return unless resource_descriptions.has_key?(version)
231
220
 
@@ -233,11 +222,11 @@ module Apipie
233
222
  # take just resources which have some methods because
234
223
  # we dont want to show eg ApplicationController as resource
235
224
  resource_descriptions[version].inject({}) do |result, (k,v)|
236
- result[k] = v.to_json unless v._methods.blank?
225
+ result[k] = v.to_json(nil, lang) unless v._methods.blank?
237
226
  result
238
227
  end
239
228
  else
240
- [@resource_descriptions[version][resource_name].to_json(method_name)]
229
+ [@resource_descriptions[version][resource_name].to_json(method_name, lang)]
241
230
  end
242
231
 
243
232
  url_args = Apipie.configuration.version_in_url ? version : ''
@@ -245,7 +234,7 @@ module Apipie
245
234
  {
246
235
  :docs => {
247
236
  :name => Apipie.configuration.app_name,
248
- :info => Apipie.app_info(version),
237
+ :info => translate(Apipie.app_info(version), lang),
249
238
  :copyright => Apipie.configuration.copyright,
250
239
  :doc_url => Apipie.full_url(url_args),
251
240
  :api_url => Apipie.api_base_url(version),
@@ -259,12 +248,18 @@ module Apipie
259
248
  end
260
249
 
261
250
  def reload_documentation
251
+ # don't load translated strings, we'll translate them later
252
+ old_locale = locale
253
+ locale = Apipie.configuration.default_locale
254
+
262
255
  rails_mark_classes_for_reload
263
256
 
264
257
  api_controllers_paths.each do |f|
265
258
  load_controller_from_file f
266
259
  end
267
260
  @checksum = nil if Apipie.configuration.update_checksum
261
+
262
+ locale = old_locale
268
263
  end
269
264
 
270
265
  def compute_checksum
@@ -311,6 +306,22 @@ module Apipie
311
306
  end
312
307
  end
313
308
 
309
+ def locale
310
+ Apipie.configuration.locale.call(nil) if Apipie.configuration.locale
311
+ end
312
+
313
+ def locale=(locale)
314
+ Apipie.configuration.locale.call(locale) if Apipie.configuration.locale
315
+ end
316
+
317
+ def translate(str, locale)
318
+ if Apipie.configuration.translate
319
+ Apipie.configuration.translate.call(str, locale)
320
+ else
321
+ str
322
+ end
323
+ end
324
+
314
325
  private
315
326
 
316
327
  def version_prefix(klass)
@@ -6,7 +6,7 @@ module Apipie
6
6
  :default_version, :debug, :version_in_url, :namespaced_resources,
7
7
  :validate, :validate_value, :validate_presence, :authenticate, :doc_path,
8
8
  :show_all_examples, :process_params, :update_checksum, :checksum_path,
9
- :link_extension
9
+ :link_extension, :record, :languages, :translate, :locale, :default_locale
10
10
 
11
11
  alias_method :validate?, :validate
12
12
  alias_method :required_by_default?, :required_by_default
@@ -141,6 +141,11 @@ module Apipie
141
141
  @checksum_path = [@doc_base_url, '/api/']
142
142
  @update_checksum = false
143
143
  @link_extension = ".html"
144
+ @record = false
145
+ @languages = []
146
+ @default_locale = 'en'
147
+ @locale = lambda { |locale| @default_locale }
148
+ @translate = lambda { |str, locale| str }
144
149
  end
145
150
  end
146
151
  end
@@ -7,17 +7,17 @@ require 'apipie/extractor/writer'
7
7
  require 'apipie/extractor/collector'
8
8
 
9
9
  class Apipie::Railtie
10
- if ENV["APIPIE_RECORD"]
11
- initializer 'apipie.extractor' do |app|
12
- ActiveSupport.on_load :action_controller do
13
- before_filter do |controller|
10
+ initializer 'apipie.extractor' do |app|
11
+ ActiveSupport.on_load :action_controller do
12
+ before_filter do |controller|
13
+ if Apipie.configuration.record
14
14
  Apipie::Extractor.call_recorder.analyse_controller(controller)
15
15
  end
16
16
  end
17
- app.middleware.use ::Apipie::Extractor::Recorder::Middleware
18
- ActionController::TestCase::Behavior.instance_eval do
19
- include Apipie::Extractor::Recorder::FunctionalTestRecording
20
- end
17
+ end
18
+ app.middleware.use ::Apipie::Extractor::Recorder::Middleware
19
+ ActionController::TestCase::Behavior.instance_eval do
20
+ include Apipie::Extractor::Recorder::FunctionalTestRecording
21
21
  end
22
22
  end
23
23
  end
@@ -28,6 +28,29 @@ module Apipie
28
28
 
29
29
  class << self
30
30
 
31
+ def start(record)
32
+ Apipie.configuration.record = record
33
+ Apipie.configuration.force_dsl = true
34
+ end
35
+
36
+ def finish
37
+ record_params, record_examples = false, false
38
+ case Apipie.configuration.record
39
+ when "params" then record_params = true
40
+ when "examples" then record_examples = true
41
+ when "all" then record_params = true, record_examples = true
42
+ end
43
+
44
+ if record_examples
45
+ puts "Writing examples to a file"
46
+ write_examples
47
+ end
48
+ if record_params
49
+ puts "Updating auto-generated documentation"
50
+ write_docs
51
+ end
52
+ end
53
+
31
54
  def logger
32
55
  Rails.logger
33
56
  end
@@ -144,28 +167,14 @@ module Apipie
144
167
  end
145
168
  end
146
169
  end
147
-
148
170
  end
149
171
  end
150
172
  end
151
173
 
152
174
  if ENV["APIPIE_RECORD"]
153
- Apipie.configuration.force_dsl = true
154
- at_exit do
155
- record_params, record_examples = false, false
156
- case ENV["APIPIE_RECORD"]
157
- when "params" then record_params = true
158
- when "examples" then record_examples = true
159
- when "all" then record_params = true, record_examples = true
160
- end
175
+ Apipie::Extractor.start ENV["APIPIE_RECORD"]
176
+ end
161
177
 
162
- if record_examples
163
- puts "Writing examples to a file"
164
- Apipie::Extractor.write_examples
165
- end
166
- if record_params
167
- puts "Updating auto-generated documentation"
168
- Apipie::Extractor.write_docs
169
- end
170
- end
178
+ at_exit do
179
+ Apipie::Extractor.finish
171
180
  end
@@ -89,7 +89,11 @@ module Apipie
89
89
  end
90
90
 
91
91
  def call(env)
92
- analyze(env) do
92
+ if Apipie.configuration.record
93
+ analyze(env) do
94
+ @app.call(env)
95
+ end
96
+ else
93
97
  @app.call(env)
94
98
  end
95
99
  end
@@ -112,15 +116,15 @@ module Apipie
112
116
 
113
117
  def process_with_api_recording(*args) # action, parameters = nil, session = nil, flash = nil, http_method = 'GET')
114
118
  ret = process_without_api_recording(*args)
115
- Apipie::Extractor.call_recorder.analyze_functional_test(self)
116
- Apipie::Extractor.call_finished
119
+ if Apipie.configuration.record
120
+ Apipie::Extractor.call_recorder.analyze_functional_test(self)
121
+ Apipie::Extractor.call_finished
122
+ end
117
123
  ret
118
124
  ensure
119
125
  Apipie::Extractor.clean_call_recorder
120
126
  end
121
127
  end
122
-
123
128
  end
124
-
125
129
  end
126
130
  end
@@ -6,15 +6,11 @@ module Apipie
6
6
 
7
7
  def initialize(collector)
8
8
  @collector = collector
9
- @examples_file = File.join(Rails.root, "doc", "apipie_examples.yml")
10
9
  end
11
10
 
12
11
  def write_examples
13
12
  merged_examples = merge_old_new_examples
14
- FileUtils.mkdir_p(File.dirname(@examples_file))
15
- File.open(@examples_file, "w") do |f|
16
- f << YAML.dump(OrderedHash[*merged_examples.sort_by(&:first).flatten(1)])
17
- end
13
+ self.class.write_recorded_examples(merged_examples)
18
14
  end
19
15
 
20
16
  def write_docs
@@ -40,8 +36,38 @@ module Apipie
40
36
  logger.warn("REST_API: Couldn't find action #{action} in #{controller}")
41
37
  end
42
38
 
39
+ def self.write_recorded_examples(examples)
40
+ examples_file = self.examples_file
41
+ FileUtils.mkdir_p(File.dirname(examples_file))
42
+ File.open(examples_file, "w") do |f|
43
+ f << JSON.pretty_generate(OrderedHash[*examples.sort_by(&:first).flatten(1)])
44
+ end
45
+ end
46
+
47
+ def self.load_recorded_examples
48
+ examples_file = self.examples_file
49
+ if File.exists?(examples_file)
50
+ return load_json_examples
51
+ end
52
+ return {}
53
+ end
54
+
55
+ def self.examples_file
56
+ File.join(Rails.root,"doc","apipie_examples.json")
57
+ end
58
+
43
59
  protected
44
60
 
61
+ def self.load_json_examples
62
+ examples = JSON.load(IO.read(examples_file))
63
+ return {} if examples.nil?
64
+ examples.each do |method, records|
65
+ records.each do |record|
66
+ record["verb"] = record["verb"].to_sym if record["verb"]
67
+ end
68
+ end
69
+ end
70
+
45
71
  def desc_to_s(description)
46
72
  "#{description[:controller].name}##{description[:action]}"
47
73
  end
@@ -61,9 +87,13 @@ module Apipie
61
87
  return ordered_call
62
88
  end
63
89
 
90
+ def load_recorded_examples
91
+ self.class.load_recorded_examples
92
+ end
93
+
64
94
  def merge_old_new_examples
65
95
  new_examples = self.load_new_examples
66
- old_examples = self.load_old_examples
96
+ old_examples = self.load_recorded_examples
67
97
  merged_examples = []
68
98
  (new_examples.keys + old_examples.keys).uniq.each do |key|
69
99
  if new_examples.has_key?(key)
@@ -364,6 +394,5 @@ module Apipie
364
394
  end
365
395
  end
366
396
  end
367
-
368
397
  end
369
398
  end
@@ -108,12 +108,12 @@ module Apipie
108
108
  return path
109
109
  end
110
110
 
111
- def method_apis_to_json
111
+ def method_apis_to_json(lang = nil)
112
112
  @apis.each.collect do |api|
113
113
  {
114
114
  :api_url => create_api_url(api),
115
115
  :http_method => api.http_method.to_s,
116
- :short_description => api.short_description
116
+ :short_description => Apipie.app.translate(api.short_description, lang)
117
117
  }
118
118
  end
119
119
  end
@@ -126,15 +126,15 @@ module Apipie
126
126
  @formats || @resource._formats
127
127
  end
128
128
 
129
- def to_json
129
+ def to_json(lang=nil)
130
130
  {
131
131
  :doc_url => doc_url,
132
132
  :name => @method,
133
- :apis => method_apis_to_json,
133
+ :apis => method_apis_to_json(lang),
134
134
  :formats => formats,
135
- :full_description => @full_description,
135
+ :full_description => Apipie.app.translate(@full_description, lang),
136
136
  :errors => errors.map(&:to_json),
137
- :params => params_ordered.map(&:to_json).flatten,
137
+ :params => params_ordered.map{ |param| param.to_json(lang) }.flatten,
138
138
  :examples => @examples,
139
139
  :metadata => @metadata,
140
140
  :see => see.map(&:to_json)