rocket_docs 0.0.2

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 (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