restility 0.0.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.
@@ -0,0 +1,158 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require "rest"
4
+
5
+ class DocBookPrinter < Printer
6
+
7
+ attr_accessor :output_dir
8
+
9
+ def initialize
10
+ super()
11
+ @output_dir = "docbook"
12
+ @xml_examples = Hash.new
13
+ @xml_schemas = Hash.new
14
+ @section = 0
15
+
16
+ @html_tag_mapping = {
17
+ "tt" => nil,
18
+ "em" => "emphasis",
19
+ "b" => "emphasis",
20
+ }
21
+ end
22
+
23
+ def do_prepare
24
+ unless File.exists? @output_dir
25
+ Dir.mkdir @output_dir
26
+ end
27
+
28
+ @index = File.new @output_dir + "/rest_api_appendix.xml", "w"
29
+ @xml = Builder::XmlMarkup.new :target => @index, :indent => 2
30
+ @xml.instruct! :xml, :version=>"1.0", :encoding=>"UTF-8"
31
+ @xml.declare! :DOCTYPE, :appendix, :PUBLIC, "-//Novell//DTD NovDoc XML V1.0//EN", "novdocx.dtd" do |x|
32
+ x.declare! :ENTITY, :%, :'NOVDOC.DEACTIVATE.IDREF', "IGNORE"
33
+ x.declare! :ENTITY, :%, :entities, :SYSTEM, "entity-decl.ent"
34
+ x << " %entities;\n"
35
+ end
36
+
37
+ @xml.comment! "This file was generated by restility at #{Time.now}"
38
+
39
+ @xml << "<appendix xml:base=\"rest_api_appendix.xml\" id=\"app.rest_api_doc\">\n"
40
+ end
41
+
42
+ def do_finish
43
+ @xml << "</appendix>\n"
44
+ puts "Written #{@index.path}"
45
+ @index.close
46
+ end
47
+
48
+ def print_section section
49
+ if !section.root?
50
+ level = section.level - 1
51
+
52
+ if level.zero?
53
+ @xml.title section
54
+ @xml.para
55
+ section.print_children self
56
+ else
57
+ @xml.tag! "sect#{level}", "id" => "app.rest_api_doc.sect#{level}.#{@section}" do
58
+ @section += 1
59
+ @xml.title section
60
+ section.print_children self
61
+ end
62
+ end
63
+ else
64
+ section.print_children self
65
+ end
66
+ end
67
+
68
+ def print_request request
69
+ @xml.variablelist do
70
+ @xml.varlistentry do
71
+
72
+ @xml.term do
73
+ @xml.literal request.to_s
74
+ end
75
+
76
+ @xml.listitem do
77
+ request.parameters.each do |p|
78
+ @xml.para do
79
+ @xml.emphasis p.name
80
+ @xml << " (optional)" if p.optional
81
+ @xml << " - #{p.description}" if p.description && !p.description.empty?
82
+ end
83
+ end
84
+
85
+ request.print_children self
86
+ end
87
+ end
88
+ end
89
+ end
90
+
91
+ def replace_html_tags text
92
+ @html_tag_mapping.each do |html, docbook|
93
+ if docbook.nil?
94
+ text.gsub! "<#{html}>", ""
95
+ else
96
+ text.gsub! "<#{html}>", "<#{docbook}>"
97
+ text.gsub! "</#{html}>", "</#{docbook}>"
98
+ end
99
+ end
100
+ end
101
+
102
+ def print_text text
103
+ @xml.para do |p|
104
+ text.text.each do |t|
105
+ replace_html_tags t
106
+ p << t << "\n"
107
+ end
108
+ end
109
+ end
110
+
111
+ def print_parameter parameter
112
+ end
113
+
114
+ def print_host host
115
+ @xml.para "Host: " + host.name
116
+ end
117
+
118
+ def print_result result
119
+ @xml.para "Result: #{result.name}"
120
+ end
121
+
122
+ def print_body body
123
+ @xml.para "Body: #{body.name}"
124
+ end
125
+
126
+ def print_xmlresult result
127
+ print_xml_links result.name, result.schema
128
+ end
129
+
130
+ def print_xmlbody body
131
+ print_xml_links body.name, body.schema
132
+ end
133
+
134
+ def print_xml_links xmlname, schema
135
+ example = xmlname + ".xml"
136
+ if !schema || schema.empty?
137
+ schema = xmlname + ".xsd"
138
+ end
139
+
140
+ if XmlFile.exist? example
141
+ @xml.screen File.read(XmlFile.find_file example)
142
+ end
143
+
144
+ if XmlFile.exist? schema
145
+ @xml.screen File.read(XmlFile.find_file schema)
146
+ end
147
+ end
148
+
149
+ def print_contents contents
150
+ # empty, the content is generated by docbook itself
151
+ @xml.para
152
+ end
153
+
154
+ def print_version version
155
+ @xml.para "API Version: #{version}"
156
+ end
157
+
158
+ end
data/lib/rest.rb ADDED
@@ -0,0 +1,459 @@
1
+ #!/usr/bin/ruby
2
+
3
+ class XmlFile
4
+
5
+ @@include_dir = ""
6
+
7
+ def XmlFile.include_dir= dir
8
+ if !dir
9
+ dir = ""
10
+ end
11
+ @@include_dir = dir
12
+ end
13
+
14
+ def XmlFile.exist? file_name
15
+ exists? file_name
16
+ end
17
+
18
+ def XmlFile.exists? file_name
19
+ find_file file_name
20
+ end
21
+
22
+ def XmlFile.copy file_name, output_dir
23
+ dir_name = File.dirname( file_name )
24
+
25
+ if ( dir_name =~ /^\// )
26
+ puts STDERR, "Absolute file names aren't allowed as XML file names."
27
+ + " (#{dir_name})";
28
+ return
29
+ end
30
+
31
+ if ( dir_name )
32
+ output_dir += "/" + dir_name
33
+ end
34
+
35
+ if ( dir_name && !dir_name.empty? && !File.exist?( dir_name ) )
36
+ `mkdir -p #{output_dir}`
37
+ if ( $? != 0 )
38
+ puts STDERR, "Unable to create directory '#{dir_name}'"
39
+ end
40
+ end
41
+ src_file = find_file( file_name )
42
+ unless File.absolute_path(output_dir) == File.absolute_path(File.split( src_file).first)
43
+ # do not copy to itself
44
+ FileUtils.cp( src_file, output_dir )
45
+ end
46
+
47
+ end
48
+
49
+ def XmlFile.find_file file_name
50
+ if ( File.exists? file_name )
51
+ return file_name
52
+ end
53
+
54
+ if ( !@@include_dir.empty? )
55
+ file_name = @@include_dir + "/" + file_name
56
+ if ( File.exists? file_name )
57
+ return file_name
58
+ end
59
+ end
60
+
61
+ return nil
62
+ end
63
+
64
+ end
65
+
66
+ class Node
67
+ attr_accessor :parent, :level, :name
68
+ attr_reader :children
69
+
70
+ def initialize n = nil
71
+ @name = n
72
+ @children = Array.new
73
+ @level = 0
74
+ end
75
+
76
+ def add_child c
77
+ @children.push c
78
+ c.parent = self
79
+ c.level = @level + 1
80
+ end
81
+
82
+ def print printer
83
+ printer.do_print self
84
+ end
85
+
86
+ def print_children printer
87
+ if ( @children )
88
+ @children.each do |child|
89
+ child.print printer
90
+ end
91
+ end
92
+ end
93
+
94
+ def root?
95
+ return !parent
96
+ end
97
+
98
+ def root
99
+ if parent
100
+ return parent.root
101
+ end
102
+ return self
103
+ end
104
+
105
+ def to_s
106
+ @name
107
+ end
108
+
109
+ def all_children type
110
+ @result = Array.new
111
+ @children.each do |child|
112
+ if ( child.class == type )
113
+ @result.push child
114
+ end
115
+ @result.concat( child.all_children( type ) )
116
+ end
117
+ @result
118
+ end
119
+
120
+ end
121
+
122
+ class Section < Node
123
+ end
124
+
125
+ class Request < Node
126
+
127
+ attr_accessor :verb, :path, :id
128
+
129
+ @@id = 0
130
+
131
+ def initialize
132
+ @id = @@id;
133
+ @@id += 1
134
+ super()
135
+ end
136
+
137
+ def to_s
138
+ p = @path.gsub(/<([^>]*?)\??>=/, "\\1=")
139
+ @verb + " " + p
140
+ end
141
+
142
+ def parameters
143
+ result = Array.new
144
+ @path.scan( /[^=]<(.*?)(\??)>/ ) do |p|
145
+ node = self
146
+ found = false
147
+ optional = $2.empty? ? false : true
148
+ while( node && !found )
149
+ node.children.each do |c|
150
+ if ( c.is_a?( Parameter ) && c.name == $1 )
151
+ c.optional = optional
152
+ result.push c
153
+ found = true
154
+ break
155
+ end
156
+ end
157
+ node = node.parent
158
+ end
159
+ if ( !found )
160
+ n = Parameter.new( $1 )
161
+ n.optional = optional
162
+ result.push n
163
+ end
164
+ end
165
+ result
166
+ end
167
+
168
+ def host
169
+ node = self
170
+ while( node )
171
+ node.children.each do |c|
172
+ if c.is_a? Host
173
+ return c
174
+ end
175
+ end
176
+ node = node.parent
177
+ end
178
+ nil
179
+ end
180
+
181
+ end
182
+
183
+ class Text < Node
184
+
185
+ attr_accessor :text
186
+
187
+ def initialize
188
+ @text = Array.new
189
+ super()
190
+ end
191
+
192
+ def to_s
193
+ @text.join("\n")
194
+ end
195
+
196
+ def append t
197
+ @text.push t
198
+ end
199
+
200
+ end
201
+
202
+ class Parameter < Node
203
+
204
+ attr_accessor :description, :optional
205
+
206
+ def initialize n = nil
207
+ @optional = false
208
+ super
209
+ end
210
+
211
+ def to_s
212
+ s = @name.to_s
213
+ s += " (optional)" if @optional
214
+ if ( !@description || @description.empty? )
215
+ s
216
+ else
217
+ s + " - " + @description
218
+ end
219
+ end
220
+
221
+ end
222
+
223
+ class Xml < Node
224
+ attr_accessor :schema
225
+ end
226
+
227
+ class Body < Node
228
+ end
229
+
230
+ class Result < Node
231
+ end
232
+
233
+ class XmlBody < Xml
234
+ end
235
+
236
+ class XmlResult < Xml
237
+ end
238
+
239
+ class Host < Node
240
+ end
241
+
242
+ class Contents < Node
243
+ end
244
+
245
+ class Version < Node
246
+ end
247
+
248
+ class Document < Section
249
+
250
+ def initialize
251
+ super
252
+ self.name = "DOCUMENT"
253
+ end
254
+
255
+ def parse_args
256
+ sections = Hash.new
257
+
258
+ sections[ 0 ] = self
259
+
260
+ @section = nil
261
+
262
+ while line = gets
263
+ if ( line =~ /^\s+(\S.*)$/ )
264
+ if ( !@text )
265
+ @text = Text.new
266
+ end
267
+ @text.append $1
268
+ else
269
+ if ( @text && @current )
270
+ @current.add_child @text
271
+ end
272
+ @text = nil
273
+ end
274
+
275
+ if ( line =~ /^(=+) (.*)/ )
276
+ level = $1.size
277
+ title = $2
278
+
279
+ @section = Section.new title
280
+ @current = @section
281
+
282
+ parent = sections[ level - 1 ]
283
+ parent.add_child @section
284
+ sections[ level ] = @section
285
+
286
+ elsif ( line =~ /^(GET|PUT|POST|DELETE) (.*)/ )
287
+ @request = Request.new
288
+ @current = @request
289
+
290
+ @request.verb = $1
291
+ @request.path = $2
292
+
293
+ @section.add_child( @request )
294
+
295
+ elsif ( line =~ /^<(.*)>: (.*)/ )
296
+ parameter = Parameter.new
297
+
298
+ parameter.name = $1
299
+ parameter.description = $2
300
+
301
+ @current.add_child( parameter )
302
+
303
+ elsif ( line =~ /^Host: (.*)/ )
304
+ host = Host.new $1
305
+ @current.add_child( host )
306
+
307
+ elsif ( line =~ /^Body: (.*)/ )
308
+ body = Body.new $1
309
+ @current.add_child( body )
310
+
311
+ elsif ( line =~ /^Result: (.*)/ )
312
+ result = Result.new $1
313
+ @current.add_child( result )
314
+
315
+ elsif ( line =~ /^XmlBody: (.*)/ )
316
+ body = XmlBody.new $1
317
+ @current.add_child( body )
318
+
319
+ elsif ( line =~ /^XmlResult: (.*) +(.*)/ )
320
+ result = XmlResult.new $1
321
+ result.schema = $2
322
+ @current.add_child( result )
323
+
324
+ elsif ( line =~ /^XmlResult: (.*)/ )
325
+ result = XmlResult.new $1
326
+ @current.add_child( result )
327
+
328
+ elsif ( line =~ /^Contents/ )
329
+ @current.add_child( Contents.new )
330
+
331
+ elsif ( line =~ /^Version: (.*)/ )
332
+ version = Version.new $1
333
+ @current.add_child( version )
334
+
335
+ end
336
+
337
+ end
338
+ end
339
+
340
+ end
341
+
342
+
343
+ class Printer
344
+
345
+ def initialize
346
+ @missing = Hash.new
347
+ end
348
+
349
+ def print node
350
+ do_prepare
351
+ do_print node
352
+ do_finish
353
+ end
354
+
355
+ def print_document printer
356
+ print_section printer
357
+ end
358
+
359
+ def do_print node
360
+ method = "print_" + node.class.to_s.downcase
361
+ send method, node
362
+ end
363
+
364
+ def do_prepare
365
+ end
366
+
367
+ def do_finish
368
+ end
369
+
370
+ def method_missing symbol, *args
371
+ if ( !@missing[ symbol ] )
372
+ @missing[ symbol ] = true
373
+ STDERR.puts "Warning: #{self.class} doesn't support '#{symbol}'."
374
+ end
375
+ end
376
+
377
+ end
378
+
379
+ class TextPrinter < Printer
380
+
381
+ def indent node
382
+ node.level.times do
383
+ printf " "
384
+ end
385
+ end
386
+
387
+ def print_section section
388
+ indent section
389
+ puts "SECTION " + section.to_s
390
+ section.print_children self
391
+ end
392
+
393
+ def print_request request
394
+ indent request
395
+ puts "Request: " + request.to_s
396
+ host = request.host
397
+ if ( host )
398
+ indent host
399
+ puts " HOST: " + host.name
400
+ end
401
+ request.parameters.each do |p|
402
+ indent request
403
+ puts " PARAMETER: #{p.to_s}"
404
+ end
405
+ request.print_children self
406
+ end
407
+
408
+ def print_text text
409
+ text.text.each do |t|
410
+ indent text
411
+ puts t
412
+ end
413
+ end
414
+
415
+ def print_parameter parameter
416
+ indent parameter
417
+ puts "PARAMETER_DEF: " + parameter.name + " - " + parameter.description
418
+ end
419
+
420
+ def print_host host
421
+ indent host
422
+ puts "HOST_DEF: " + host.name
423
+ end
424
+
425
+ def print_result result
426
+ indent result
427
+ puts "Result: " + result.name
428
+ end
429
+
430
+ def print_xmlresult result
431
+ indent result
432
+ printf "XmlResult: " + result.name
433
+ if ( result.schema )
434
+ printf " (Schema: #{result.schema})"
435
+ end
436
+ printf "\n"
437
+ end
438
+
439
+ def print_body body
440
+ indent body
441
+ puts "Body: " + body.name
442
+ end
443
+
444
+ end
445
+
446
+
447
+ class OutlinePrinter < Printer
448
+ def print node
449
+ node.level.times do
450
+ printf " "
451
+ end
452
+ puts "#{node.level} #{node.class}"
453
+ node.print_children self
454
+ end
455
+
456
+ def print_section node
457
+ print node
458
+ end
459
+ end