rocket_docs 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/Rakefile +24 -0
  4. data/app/assets/javascripts/rocket_docs/application.js +206 -0
  5. data/app/assets/stylesheets/rocket_docs/application.scss +51 -0
  6. data/app/controllers/rocket_docs/application_controller.rb +13 -0
  7. data/app/helpers/rocket_docs/application_helper.rb +24 -0
  8. data/app/views/docs/rocket_docs/_action.markdown.erb +23 -0
  9. data/app/views/docs/rocket_docs/_action.slim +43 -0
  10. data/app/views/docs/rocket_docs/_controller.markdown.erb +7 -0
  11. data/app/views/docs/rocket_docs/_controller.slim +9 -0
  12. data/app/views/docs/rocket_docs/_documentation.markdown.erb +4 -0
  13. data/app/views/docs/rocket_docs/_documentation.slim +3 -0
  14. data/app/views/docs/rocket_docs/_hash_param.slim +7 -0
  15. data/app/views/docs/rocket_docs/_version.slim +7 -0
  16. data/app/views/docs/rocket_docs/index.slim +3 -0
  17. data/app/views/docs/rocket_docs/show.markdown.erb +3 -0
  18. data/app/views/docs/rocket_docs/show.slim +4 -0
  19. data/app/views/layouts/rocket_docs/_modal.slim +12 -0
  20. data/app/views/layouts/rocket_docs/_navigation.slim +10 -0
  21. data/app/views/layouts/rocket_docs/application.slim +9 -0
  22. data/config/routes.rb +5 -0
  23. data/lib/rocket_docs/documentation/action.rb +98 -0
  24. data/lib/rocket_docs/documentation/controller.rb +57 -0
  25. data/lib/rocket_docs/documentation.rb +46 -0
  26. data/lib/rocket_docs/engine.rb +12 -0
  27. data/lib/rocket_docs/parser.rb +105 -0
  28. data/lib/rocket_docs/router.rb +86 -0
  29. data/lib/rocket_docs/version.rb +3 -0
  30. data/lib/rocket_docs.rb +30 -0
  31. data/lib/tasks/rocket_docs_tasks.rake +85 -0
  32. metadata +284 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 97e8e49ad6cf5ad899dd4e256ea5ef36e34f259b
4
+ data.tar.gz: 4b7ed20c4cdb13d88576684948e01d903be40665
5
+ SHA512:
6
+ metadata.gz: c5c728791f5e8e6d2590e0fac023314a962c2b2fa211d2b6bd1ecd9b0087430a430e3d2337cfe35c449104bb0ed0ca3587847d5230b1974c36d2c501ac28b51b
7
+ data.tar.gz: dbd9b9939b76bcf4a00c14b8b775a66e0fdbd5062be68a96f5125545f5cd285d6e1cc27af65cfb033c9a379d353324eecd0993774734a83474ffb493caf75fcd
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2015 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,24 @@
1
+ begin
2
+ require 'rubygems'
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+
8
+ require 'rdoc/task'
9
+
10
+ RDoc::Task.new(:rdoc) do |rdoc|
11
+ rdoc.rdoc_dir = 'rdoc'
12
+ rdoc.title = 'RocketDocs'
13
+ rdoc.options << '--line-numbers'
14
+ rdoc.rdoc_files.include('README.rdoc')
15
+ rdoc.rdoc_files.include('lib/**/*.rb')
16
+ end
17
+
18
+ APP_RAKEFILE = File.expand_path('../spec/test_app/Rakefile', __FILE__)
19
+ load 'rails/tasks/engine.rake'
20
+
21
+ Bundler::GemHelper.install_tasks
22
+
23
+ RSpec::Core::RakeTask.new(:spec)
24
+ task default: :appraisal if !ENV['APPRAISAL_INITIALIZED'] && !ENV['TRAVIS']
@@ -0,0 +1,206 @@
1
+ //= require jquery
2
+ //= require jquery_ujs
3
+ //= require bootstrap
4
+
5
+ $(document).ready(function () {
6
+ $('#try-out-modal').on('show.bs.modal', function (event) {
7
+ var $modal = $(this);
8
+ var $triggerButton = $(event.relatedTarget);
9
+ var $testButton = $modal.find('.btn.try');
10
+ $modal.find('h4.modal-title').text('' +
11
+ $triggerButton.data('request-method') + ' ' + $triggerButton.data('url')
12
+ );
13
+ $modal.find('.modal-body').html(
14
+ contentForModal(
15
+ $triggerButton.data('url'),
16
+ $triggerButton.data('request-method'),
17
+ $triggerButton.data('params'),
18
+ $triggerButton.data('saved_params'),
19
+ $triggerButton.data('saved_text')
20
+ )
21
+ );
22
+ $testButton.click(function(){
23
+ saveParams($modal.find('.modal-body'), $triggerButton);
24
+ var $response = $modal.find('.response');
25
+
26
+ $modal.find('.response-body').removeClass('hidden');
27
+ addSpinner($response);
28
+
29
+ $.ajax(
30
+ buildRequestParams($modal.find('.modal-body'), $triggerButton.data('url'), $triggerButton.data('request-method'))
31
+ ).done(function(data, textStatus, jqXHR) {
32
+ var response = jqXHR.responseText;
33
+
34
+ $response.html('');
35
+ $response.text(response);
36
+ $(window).trigger('resize');
37
+ });
38
+ });
39
+ }).on('hidden.bs.modal', function () {
40
+ var $modal = $(this);
41
+ $modal.find('h4.modal-title').text('Try it');
42
+ $modal.find('.modal-body').html('');
43
+ });
44
+
45
+ function buildRequestParams($object, url, method) {
46
+ var $inputs = $object.find('input[data-key]');
47
+ var $requestBody = $object.find('textarea');
48
+ var data = null;
49
+ var processData = true;
50
+
51
+ if ($inputs.length !== 0) {
52
+ data = {};
53
+ $inputs.each(function(i, $input) {
54
+ $input = $($input);
55
+ if (url.indexOf('{' + $input.data('key') + '}')) {
56
+ url = url.replace('{' + $input.data('key') + '}', $input.val());
57
+ } else {
58
+ data[$input.data('key')] = $input.val();
59
+ }
60
+ });
61
+ }
62
+ if ($requestBody.length !== 0) {
63
+ processData = false;
64
+ data = $requestBody.val();
65
+ }
66
+
67
+ return {
68
+ url: url,
69
+ type: method,
70
+ processData: processData,
71
+ data: data
72
+ };
73
+ }
74
+
75
+ function saveParams($object, $saveToObject) {
76
+ var $inputs = $object.find('input[data-key]');
77
+ var $requestBody = $object.find('textarea');
78
+
79
+ if ($inputs.length !== 0) {
80
+ var params = {};
81
+ $inputs.each(function(i, $input) {
82
+ $input = $($input);
83
+ params[$input.data('key')] = $input.val();
84
+ });
85
+ $saveToObject.data('saved_params', params);
86
+ }
87
+
88
+ if ($requestBody.length !== 0) {
89
+ $saveToObject.data('saved_text', $requestBody.val());
90
+ }
91
+
92
+ return true;
93
+ }
94
+
95
+ function addSpinner($object) {
96
+ var message = '<center>'+
97
+ '<span class="glyphicon glyphicon-refresh gly-spin"></span>'+
98
+ ' Waiting for response...'+
99
+ '</center>';
100
+ $object.html(message);
101
+ }
102
+
103
+ function contentForModal(url, method, params, savedParams, savedText) {
104
+ var content = '';
105
+ content += '<h3>Request body</h3>';
106
+ if (method === 'GET' && params) {
107
+ content += paramsInputTable(params, savedParams);
108
+ } else {
109
+ var regex = /\{[^\s]+\}/;
110
+ var match = regex.exec(url);
111
+ if (match && match.length !== 0) {
112
+ var tempParams = {};
113
+ $.each(match, function(i, m) {
114
+ tempParams[m.replace(/[\{\}]/g,'')] = i;
115
+ });
116
+ content += paramsInputTable(tempParams, savedParams);
117
+ }
118
+ var saved = '';
119
+ if (savedText) {
120
+ saved = savedText;
121
+ }
122
+ content += '<textarea class="form-control" rows="6" cols="90">' + saved + '</textarea>';
123
+ }
124
+ if (method !== 'GET' && params) {
125
+ content += '<h4>Expected params</h4>';
126
+ content += paramsTable(params);
127
+ }
128
+ content += '<div class="response-body hidden">';
129
+ content += '<hr>';
130
+ content += '<h3>Response</h3>';
131
+ content += '<pre><code class="response"></code></pre>';
132
+ content += '</div>';
133
+
134
+ return content;
135
+ }
136
+
137
+ function paramsInputTable(params, savedParams) {
138
+ var content = '<table class="table table-striped">';
139
+ content += '<thead>';
140
+ content += '<tr>'+
141
+ '<th>Param</th>'+
142
+ '<th>Value</th>'+
143
+ '</tr>';
144
+ content += '</thead>';
145
+ $.each(params, function(k, v) {
146
+ content += paramsInputTableRow(k, v, null, savedParams);
147
+ });
148
+ content += '</table>';
149
+ return content;
150
+ }
151
+
152
+ function paramsInputTableRow(k, v, wrapper, savedParams) {
153
+ var content = '';
154
+ var saved = '';
155
+ if (wrapper) {
156
+ k = wrapper + '[' + k + ']';
157
+ }
158
+ if (savedParams && savedParams[k]) {
159
+ saved = savedParams[k];
160
+ }
161
+ if (typeof v === 'object') {
162
+ $.each(v, function(kk, vv) {
163
+ content += paramsInputTableRow(kk, vv, k, savedParams);
164
+ });
165
+ } else {
166
+ content += '<tr>'+
167
+ '<td>' + k + '</td>'+
168
+ '<td><input type="text" class="form-control" value="' + saved + '" data-key="' + k + '"></td>'+
169
+ '</tr>';
170
+ }
171
+ return content;
172
+ }
173
+
174
+ function paramsTable(params) {
175
+ var content = '<table class="table table-striped">';
176
+ content += '<thead>';
177
+ content += '<tr>'+
178
+ '<th>Name</th>'+
179
+ '<th>Type</th>'+
180
+ '</tr>';
181
+ content += '</thead>';
182
+ $.each(params, function(k, v){
183
+ content += paramsTableRow(k, v, null);
184
+ });
185
+ content += '</table>';
186
+ return content;
187
+ }
188
+
189
+ function paramsTableRow(k, v, wrapper) {
190
+ var content = '';
191
+ if (wrapper) {
192
+ k = wrapper + '[' + k + ']';
193
+ }
194
+ if (typeof v === 'object') {
195
+ $.each(v, function(kk, vv) {
196
+ content += paramsTableRow(kk, vv, k);
197
+ });
198
+ } else {
199
+ content += '<tr>'+
200
+ '<td>' + k + '</td>'+
201
+ '<td>' + v + '</td>'+
202
+ '</tr>';
203
+ }
204
+ return content;
205
+ }
206
+ });
@@ -0,0 +1,51 @@
1
+ /*
2
+ *= require_tree .
3
+ *= require_self
4
+ */
5
+ @import "bootstrap-sprockets";
6
+ @import "bootstrap";
7
+
8
+ body {
9
+ padding-top: 70px;
10
+ }
11
+
12
+ .gly-spin {
13
+ -webkit-animation: spin 2s infinite linear;
14
+ -moz-animation: spin 2s infinite linear;
15
+ -o-animation: spin 2s infinite linear;
16
+ animation: spin 2s infinite linear;
17
+ }
18
+ @-moz-keyframes spin {
19
+ 0% {
20
+ -moz-transform: rotate(0deg);
21
+ }
22
+ 100% {
23
+ -moz-transform: rotate(359deg);
24
+ }
25
+ }
26
+ @-webkit-keyframes spin {
27
+ 0% {
28
+ -webkit-transform: rotate(0deg);
29
+ }
30
+ 100% {
31
+ -webkit-transform: rotate(359deg);
32
+ }
33
+ }
34
+ @-o-keyframes spin {
35
+ 0% {
36
+ -o-transform: rotate(0deg);
37
+ }
38
+ 100% {
39
+ -o-transform: rotate(359deg);
40
+ }
41
+ }
42
+ @keyframes spin {
43
+ 0% {
44
+ -webkit-transform: rotate(0deg);
45
+ transform: rotate(0deg);
46
+ }
47
+ 100% {
48
+ -webkit-transform: rotate(359deg);
49
+ transform: rotate(359deg);
50
+ }
51
+ }
@@ -0,0 +1,13 @@
1
+ module RocketDocs
2
+ class ApplicationController < ActionController::Base
3
+ def index
4
+ @docs = RocketDocs.documentation
5
+ render 'docs/rocket_docs/index'
6
+ end
7
+
8
+ def show
9
+ @doc = RocketDocs.documentation_for_version(params[:version])
10
+ render 'docs/rocket_docs/show'
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,24 @@
1
+ module RocketDocs
2
+ module ApplicationHelper
3
+ def doc_id(doc)
4
+ "version_#{web_safe(doc.version)}"
5
+ end
6
+
7
+ def controller_id(controller)
8
+ "#{doc_id(controller.documentation)}_controller_"\
9
+ "#{web_safe(controller.name)}"
10
+ end
11
+
12
+ def action_id(action)
13
+ "#{controller_id(action.controller)}_action_#{web_safe(action.name)}"
14
+ end
15
+
16
+ def method_id(action, method)
17
+ "#{action_id(action)}_method_#{web_safe(method)}"
18
+ end
19
+
20
+ def web_safe(string)
21
+ string.to_s.humanize.sub(' ', '').underscore
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,23 @@
1
+ ### <%= action.name %>
2
+
3
+ <% action.methods.each do |method| %>
4
+ #### <%= method.upcase %>
5
+
6
+ > __URL:__ <%= '' || action.url %>
7
+
8
+ <% if action.description(method) %>
9
+ >__DESCRIPTION:__ <%= action.description(method) %>
10
+ <% end %>
11
+
12
+ <% if action.params(method) %>
13
+ >__PARAMS:__
14
+
15
+ >| Name | Type |
16
+ >| ---- | ---- |
17
+ <% action.params(method).each do |k, v| %>
18
+ >| <%= k %> | <%= v %> |
19
+ <% end %>
20
+ <% end %>
21
+
22
+
23
+ <% end %>
@@ -0,0 +1,43 @@
1
+ .panel.panel-default
2
+ .panel-heading
3
+ h4.panel-title
4
+ = link_to "#{action.name}", "##{action_id(action)}", data: { toggle: 'collapse' }
5
+ .panel-collapse.collapse id="#{action_id(action)}"
6
+ .panel-body
7
+ ul.nav.nav-tabs
8
+ - action.methods.each_with_index do |method, index|
9
+ li class="#{index == 0 ? 'active' : ''}"
10
+ = link_to method.upcase, "##{method_id(action, method)}", data: { toggle: 'tab' }
11
+ .tab-content
12
+ - action.methods.each_with_index do |method, index|
13
+ .tab-pane class="#{index == 0 ? 'active' : ''}" id="#{method_id(action, method)}"
14
+
15
+ .col-md-6
16
+ .row
17
+ .col-xs-12
18
+ - if action.url(method)
19
+ h4 URL
20
+ = action.url
21
+ .col-xs-12
22
+ - if action.description(method)
23
+ h4 Description
24
+ = simple_format(action.description(method))
25
+ .col-md-6
26
+ .row
27
+ .col-xs-12
28
+ - if action.params(method)
29
+ h4 Params
30
+ table.table.table-striped
31
+ thead
32
+ tr
33
+ th Name
34
+ th Type
35
+ tbody
36
+ = render 'docs/rocket_docs/hash_param', hash: action.params(method), wrap: nil
37
+
38
+ - if action.url(method)
39
+ .col-xs-12
40
+ hr
41
+ = link_to '#', class: 'btn btn-primary try-out', data: { request_method: method, params: action.params(method), url: action.url, toggle: 'modal', target: '#try-out-modal' } do
42
+ span.glyphicon.glyphicon-new-window
43
+ | Try it out
@@ -0,0 +1,7 @@
1
+ ## <%= controller.name %>
2
+
3
+ <% controller.actions.each do |action| %>
4
+ <%= render 'docs/rocket_docs/action.markdown.erb', action: action %>
5
+
6
+ ___
7
+ <% end %>
@@ -0,0 +1,9 @@
1
+ .panel.panel-default
2
+ .panel-heading
3
+ h4.panel-title
4
+ = link_to "#{controller.name}", "##{controller_id(controller)}", data: { toggle: 'collapse' }
5
+ .panel-collapse.collapse id="#{controller_id(controller)}"
6
+ .panel-body
7
+ .panel-group id="#{controller_id(controller)}_accordion"
8
+ - controller.actions.each do |action|
9
+ = render 'docs/rocket_docs/action', action: action
@@ -0,0 +1,4 @@
1
+ <% doc.controllers.each do |controller| %>
2
+ <%= render 'docs/rocket_docs/controller.markdown.erb', controller: controller %>
3
+
4
+ <% end %>
@@ -0,0 +1,3 @@
1
+ .panel-group id="#{doc_id(doc)}_accordion"
2
+ - doc.controllers.each do |controller|
3
+ = render 'docs/rocket_docs/controller', controller: controller
@@ -0,0 +1,7 @@
1
+ - hash.each do |k, v|
2
+ - if v.is_a?(Hash)
3
+ = render 'docs/rocket_docs/hash_param', hash: v, wrap: wrap ? "#{wrap}[#{k}]" : k
4
+ - else
5
+ tr
6
+ td = wrap ? "#{wrap}[#{k}]" : k
7
+ td = v
@@ -0,0 +1,7 @@
1
+ .panel.panel-default
2
+ .panel-heading
3
+ h4.panel-title
4
+ = link_to "Version #{doc.version}", "##{doc_id(doc)}", data: { toggle: 'collapse' }
5
+ .panel-collapse.collapse id="#{doc_id(doc)}"
6
+ .panel-body
7
+ = render 'docs/rocket_docs/documentation', doc: doc
@@ -0,0 +1,3 @@
1
+ .panel-group#versions_accordion
2
+ - @docs.each do |doc|
3
+ = render 'docs/rocket_docs/version', doc: doc
@@ -0,0 +1,3 @@
1
+ # <%= @doc.version %>
2
+
3
+ <%= render 'docs/rocket_docs/documentation.markdown.erb', doc: @doc %>
@@ -0,0 +1,4 @@
1
+ h1= @doc.version
2
+ hr
3
+ .col-xs-12
4
+ = render 'docs/rocket_docs/documentation', doc: @doc
@@ -0,0 +1,12 @@
1
+ .modal.fade#try-out-modal
2
+ .modal-dialog
3
+ .modal-content
4
+ .modal-header
5
+ button.close data-dismiss='modal'
6
+ h4.modal-title Try it
7
+ .modal-body
8
+ .modal-footer
9
+ button.btn.btn-default data-dismiss='modal'
10
+ | Close
11
+ button.btn.btn-primary.try
12
+ | Try it
@@ -0,0 +1,10 @@
1
+ - if defined?(rocket_docs)
2
+ .navbar.navbar-default.navbar-fixed-top
3
+ .container-fluid
4
+ .navbar-header
5
+ = link_to 'Documentation', rocket_docs.root_path, class: 'navbar-brand'
6
+ .collapse.navbar-collapse
7
+ ul.nav.navbar-nav
8
+ li = link_to 'All versions', rocket_docs.root_path
9
+ - RocketDocs::Router.versions.each do |v|
10
+ li = link_to v.to_s, rocket_docs.version_path(version: v)
@@ -0,0 +1,9 @@
1
+ head
2
+ title RocketDocs
3
+ = stylesheet_link_tag "rocket_docs/application", media: "all"
4
+ = javascript_include_tag "rocket_docs/application"
5
+ body
6
+ = render 'layouts/rocket_docs/navigation'
7
+ .container
8
+ = yield
9
+ = render 'layouts/rocket_docs/modal'
data/config/routes.rb ADDED
@@ -0,0 +1,5 @@
1
+ RocketDocs::Engine.routes.draw do
2
+ root 'application#index'
3
+ get 'versions', to: 'application#index', as: 'versions'
4
+ get 'version/:version', to: 'application#show', as: 'version'
5
+ end
@@ -0,0 +1,98 @@
1
+ module RocketDocs
2
+ class Documentation
3
+ class Action
4
+ attr_reader :name
5
+ attr_reader :controller
6
+ attr_reader :comments
7
+
8
+ def initialize(name, comments, methods, params, controller)
9
+ @name = name
10
+ @comments = comments
11
+ @methods = sanitize_methods(methods)
12
+ @params = params
13
+ @params.delete(:version) if params
14
+ @params = @params.presence
15
+ @controller = controller
16
+ generate
17
+ end
18
+
19
+ def url(method = default_method)
20
+ (@doc[method] && @doc[method]['URL']) || @doc['URL'] ||
21
+ router_url(method)
22
+ end
23
+
24
+ def description(method = default_method)
25
+ desc = (@doc[method] && @doc[method]['DOC']) || @doc['DOC']
26
+ desc && CGI.escapeHTML(desc).gsub("\n", '<br>').html_safe
27
+ end
28
+
29
+ def params(method = default_method)
30
+ (@doc[method] && @doc[method]['PARAMS']) || @doc['PARAMS'] ||
31
+ @params
32
+ end
33
+
34
+ def default_method
35
+ methods.first || 'GET'
36
+ end
37
+
38
+ def methods
39
+ @methods.presence ||
40
+ @doc.keys.select { |m| Parser.http_keywords.include?(m) }
41
+ end
42
+
43
+ private
44
+
45
+ def generate
46
+ return @doc = {} unless @comments.present?
47
+ @doc = RocketDocs::Parser.parse_comments(@comments).value
48
+ end
49
+
50
+ def _routes
51
+ RocketDocs::Router.app_routes
52
+ end
53
+
54
+ def sanitize_methods(methods)
55
+ return unless methods
56
+ methods.map do |m|
57
+ if m.is_a?(String)
58
+ m
59
+ else
60
+ m.to_s.sub('(?-mix:^', '').sub('$)', '').split('|')
61
+ end
62
+ end.flatten
63
+ end
64
+
65
+ def router_url(method = default_method)
66
+ route = _routes.url_for(url_params(method))
67
+ route = route.split('?').first unless method == 'GET'
68
+ CGI.unescape(route)
69
+ rescue ActionController::UrlGenerationError
70
+ nil
71
+ end
72
+
73
+ def url_params(method = default_method)
74
+ hash = {}
75
+ hash = deflated_url_params(params(method)) if @params
76
+ hash.merge(
77
+ controller: controller.full_name.downcase,
78
+ action: name,
79
+ version: controller.documentation.version,
80
+ only_path: true
81
+ )
82
+ end
83
+
84
+ def deflated_url_params(hash, wrapper = nil)
85
+ nh = {}
86
+ hash.each do |k, v|
87
+ new_v = wrapper ? "#{wrapper}[#{k}]" : k
88
+ if v.is_a?(Hash)
89
+ nh[k] = deflated_url_params(v, k)
90
+ else
91
+ nh[k] = "{#{new_v}}"
92
+ end
93
+ end
94
+ nh.symbolize_keys
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,57 @@
1
+ module RocketDocs
2
+ class Documentation
3
+ class Controller
4
+ attr_accessor :name
5
+ attr_accessor :file
6
+ attr_reader :documentation
7
+ attr_reader :actions
8
+
9
+ def initialize(name, file, actions_hash, documentation)
10
+ @file_md5 = ''
11
+ @actions = []
12
+ @actions_in = actions_hash
13
+ self.name = name
14
+ self.file = file
15
+ @documentation = documentation
16
+ update!
17
+ end
18
+
19
+ def update
20
+ should_update? && update!
21
+ end
22
+
23
+ def update!
24
+ @file_md5 = generate_hash
25
+ generate
26
+ end
27
+
28
+ def should_update?
29
+ return false if generate_hash == @file_md5
30
+ true
31
+ end
32
+
33
+ def name
34
+ return unless @name
35
+ @name.split('/').last.sub('_controller', '').humanize
36
+ end
37
+
38
+ def full_name
39
+ @name
40
+ end
41
+
42
+ private
43
+
44
+ def generate
45
+ @actions = []
46
+ comments = RocketDocs::Parser.method_comments(file)
47
+ @actions_in.each do |name, action|
48
+ @actions << Action.new(name, comments[name], action[:methods], action[:params], self)
49
+ end
50
+ end
51
+
52
+ def generate_hash
53
+ Digest::MD5.file(file).hexdigest
54
+ end
55
+ end
56
+ end
57
+ end