docapi 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +5 -0
- data/LICENSE +20 -0
- data/README.rdoc +7 -0
- data/Rakefile +57 -0
- data/VERSION +1 -0
- data/bin/docapi +47 -0
- data/docapi.gemspec +76 -0
- data/files/javascripts/documentation/documentation.js +26 -0
- data/files/javascripts/documentation/highlight.pack.js +1 -0
- data/files/javascripts/documentation/jquery-1.3.2.min.js +19 -0
- data/files/javascripts/documentation/jquery.tableofcontents.min.js +12 -0
- data/files/stylesheets/documentation/highlighter/ascetic.css +42 -0
- data/files/stylesheets/documentation/highlighter/brown_paper.css +104 -0
- data/files/stylesheets/documentation/highlighter/brown_papersq.png +0 -0
- data/files/stylesheets/documentation/highlighter/dark.css +101 -0
- data/files/stylesheets/documentation/highlighter/default.css +103 -0
- data/files/stylesheets/documentation/highlighter/far.css +113 -0
- data/files/stylesheets/documentation/highlighter/github.css +90 -0
- data/files/stylesheets/documentation/highlighter/idea.css +74 -0
- data/files/stylesheets/documentation/highlighter/ir_black.css +67 -0
- data/files/stylesheets/documentation/highlighter/magula.css +105 -0
- data/files/stylesheets/documentation/highlighter/school_book.css +106 -0
- data/files/stylesheets/documentation/highlighter/school_book.png +0 -0
- data/files/stylesheets/documentation/highlighter/sunburst.css +112 -0
- data/files/stylesheets/documentation/highlighter/vs.css +68 -0
- data/files/stylesheets/documentation/highlighter/zenburn.css +113 -0
- data/files/stylesheets/documentation/layout.css +161 -0
- data/lib/docapi.rb +150 -0
- data/test/code/reference_api.rb +141 -0
- data/test/doc/1-README.md +17 -0
- data/test/doc/2-documentation/documentation.html +186 -0
- data/test/doc/3-tutorials/2-ruby/example-1.rb +12 -0
- metadata +89 -0
@@ -0,0 +1,113 @@
|
|
1
|
+
/*
|
2
|
+
|
3
|
+
Zenburn style from voldmar.ru (c) Vladimir Epifanov <voldmar@voldmar.ru>
|
4
|
+
based on dark.css by Ivan Sagalaev
|
5
|
+
|
6
|
+
*/
|
7
|
+
|
8
|
+
pre code[class]:after {
|
9
|
+
content: 'highlight: ' attr(class);
|
10
|
+
display: block; text-align: right;
|
11
|
+
font-size: smaller;
|
12
|
+
color: #CCC; background: white;
|
13
|
+
border-top: solid 1px black;
|
14
|
+
padding-top: 0.5em;
|
15
|
+
}
|
16
|
+
|
17
|
+
pre code {
|
18
|
+
display: block;
|
19
|
+
background: #3F3F3F;
|
20
|
+
color: #DCDCDC;
|
21
|
+
}
|
22
|
+
|
23
|
+
.keyword,
|
24
|
+
.tag,
|
25
|
+
.django .tag,
|
26
|
+
.django .keyword,
|
27
|
+
.css .class,
|
28
|
+
.css .id,
|
29
|
+
.lisp .title {
|
30
|
+
color: #E3CEAB;
|
31
|
+
}
|
32
|
+
|
33
|
+
.django .template_tag,
|
34
|
+
.django .variable,
|
35
|
+
.django .filter .argument {
|
36
|
+
color: #DCDCDC;
|
37
|
+
}
|
38
|
+
|
39
|
+
.number,
|
40
|
+
.date {
|
41
|
+
color: #8CD0D3;
|
42
|
+
}
|
43
|
+
|
44
|
+
.dos .envvar,
|
45
|
+
.dos .stream,
|
46
|
+
.variable,
|
47
|
+
.apache .sqbracket {
|
48
|
+
color: #EFDCBC;
|
49
|
+
}
|
50
|
+
|
51
|
+
.dos .flow,
|
52
|
+
.diff .change,
|
53
|
+
.python .exception,
|
54
|
+
.python .built_in,
|
55
|
+
.literal {
|
56
|
+
color: #EFEFAF;
|
57
|
+
}
|
58
|
+
|
59
|
+
.diff .chunk,
|
60
|
+
.ruby .subst {
|
61
|
+
color: #8F8F8F;
|
62
|
+
}
|
63
|
+
|
64
|
+
.dos .keyword,
|
65
|
+
.python .decorator,
|
66
|
+
.class .title,
|
67
|
+
.function .title,
|
68
|
+
.ini .title,
|
69
|
+
.diff .header,
|
70
|
+
.ruby .class .parent,
|
71
|
+
.apache .tag {
|
72
|
+
color: #efef8f;
|
73
|
+
}
|
74
|
+
|
75
|
+
.dos .winutils,
|
76
|
+
.ruby .symbol,
|
77
|
+
.ruby .string,
|
78
|
+
.ruby .instancevar {
|
79
|
+
color: #DCA3A3;
|
80
|
+
}
|
81
|
+
|
82
|
+
.diff .deletion,
|
83
|
+
.string,
|
84
|
+
.tag .attribute .value,
|
85
|
+
.preprocessor,
|
86
|
+
.built_in,
|
87
|
+
.sql .aggregate,
|
88
|
+
.javadoc,
|
89
|
+
.smalltalk .class,
|
90
|
+
.smalltalk .localvars,
|
91
|
+
.smalltalk .array,
|
92
|
+
.css .rules .value,
|
93
|
+
.attr_selector,
|
94
|
+
.pseudo,
|
95
|
+
.apache .cbracket {
|
96
|
+
color: #CC9393;
|
97
|
+
}
|
98
|
+
|
99
|
+
.shebang,
|
100
|
+
.diff .addition,
|
101
|
+
.comment,
|
102
|
+
.java .annotation,
|
103
|
+
.template_comment,
|
104
|
+
.pi,
|
105
|
+
.doctype {
|
106
|
+
color: #7F9F7F;
|
107
|
+
}
|
108
|
+
|
109
|
+
.html .css,
|
110
|
+
.html .javascript {
|
111
|
+
opacity: 0.5;
|
112
|
+
}
|
113
|
+
|
@@ -0,0 +1,161 @@
|
|
1
|
+
body {
|
2
|
+
/* font-size: 16px;*/
|
3
|
+
color:black;
|
4
|
+
font-family:Lucida Grande,Verdana,Arial,Helvetica,sans-serif;
|
5
|
+
font-size:90%;
|
6
|
+
width: auto;
|
7
|
+
margin: auto;
|
8
|
+
padding: 20px 300px 20px 40px;
|
9
|
+
}
|
10
|
+
h1, h2, h3, h4, h5 {
|
11
|
+
position: relative;
|
12
|
+
}
|
13
|
+
h1 {
|
14
|
+
border-bottom: 1px solid #eee;
|
15
|
+
color:#0E3062;
|
16
|
+
font-size:1.8em;
|
17
|
+
margin:0.8em 0 0.3em;
|
18
|
+
}
|
19
|
+
h2 {
|
20
|
+
font-size: 1.4em;
|
21
|
+
font-family: 'Bitstream Vera Sans Mono', Monaco, monospace, courier, 'courier new';
|
22
|
+
}
|
23
|
+
h3 {
|
24
|
+
font-family: "Courier New";
|
25
|
+
}
|
26
|
+
pre
|
27
|
+
{
|
28
|
+
/* margin: 0 0 10px 0;*/
|
29
|
+
/* padding: 10px;*/
|
30
|
+
font-size: 12px;
|
31
|
+
line-height: 150%;
|
32
|
+
font-family: 'Bitstream Vera Sans Mono', Monaco, monospace, courier, 'courier new';
|
33
|
+
background: #F8F8FF;
|
34
|
+
color: #111;
|
35
|
+
/* border: 1px solid #ddd;*/
|
36
|
+
}
|
37
|
+
pre.hidden {
|
38
|
+
cursor: pointer;
|
39
|
+
}
|
40
|
+
code, tt {
|
41
|
+
overflow: auto;
|
42
|
+
font-family: 'Bitstream Vera Sans Mono', Monaco, monospace, courier, 'courier new';
|
43
|
+
padding: 0 2px;
|
44
|
+
background: #f1f1f1;
|
45
|
+
font-size: .9em;
|
46
|
+
border-bottom: 1px solid #ddd;
|
47
|
+
}
|
48
|
+
|
49
|
+
pre.hidden:after {
|
50
|
+
content: 'hidden';
|
51
|
+
display: block; text-align: center;
|
52
|
+
font-size: smaller;
|
53
|
+
color: #000; background: white;
|
54
|
+
border-top: solid 1px #ccc;
|
55
|
+
padding-top: 0.5em;
|
56
|
+
}
|
57
|
+
|
58
|
+
pre code
|
59
|
+
{
|
60
|
+
background: transparent;
|
61
|
+
}
|
62
|
+
|
63
|
+
table.code {
|
64
|
+
width: 100%;
|
65
|
+
}
|
66
|
+
|
67
|
+
div.code pre {
|
68
|
+
margin: 0;
|
69
|
+
}
|
70
|
+
p {
|
71
|
+
margin-top: 0px;
|
72
|
+
margin-bottom: 0.5em;
|
73
|
+
}
|
74
|
+
li > p:first-child:first-line {
|
75
|
+
background-color: #ffffe0;
|
76
|
+
padding: 0px 8px;
|
77
|
+
}
|
78
|
+
span.replace {
|
79
|
+
color: orange;
|
80
|
+
}
|
81
|
+
a > span.replace {
|
82
|
+
color: inherit;
|
83
|
+
}
|
84
|
+
|
85
|
+
p.page-title {
|
86
|
+
color: #880000;
|
87
|
+
font-weight: bold;
|
88
|
+
font-size: 2em;
|
89
|
+
}
|
90
|
+
.docapi-section {
|
91
|
+
margin-left: 15px;
|
92
|
+
}
|
93
|
+
.docapi-subsection {
|
94
|
+
padding: 5px;
|
95
|
+
margin-bottom: 20px;
|
96
|
+
}
|
97
|
+
.docapi-subsection .docapi-title {
|
98
|
+
padding: 3px 10px;
|
99
|
+
font-size: 1.4em;
|
100
|
+
background: #336699;
|
101
|
+
color: #fff;
|
102
|
+
margin-bottom: 10px;
|
103
|
+
font-weight: bold;
|
104
|
+
font-family: "Courier New";
|
105
|
+
}
|
106
|
+
.docapi-subsection .docapi-subtitle {
|
107
|
+
font-size: 1.1em;
|
108
|
+
font-weight: bold;
|
109
|
+
font-family: 'Bitstream Vera Sans Mono', Monaco, monospace, courier, 'courier new';
|
110
|
+
margin:20px 2px 5px 0px;
|
111
|
+
border-left: 5px solid orange;
|
112
|
+
padding-left: 5px;
|
113
|
+
}
|
114
|
+
table {
|
115
|
+
font-size: 0.8em;
|
116
|
+
}
|
117
|
+
|
118
|
+
/*#toc {
|
119
|
+
float: right;
|
120
|
+
font-size: 10pt;
|
121
|
+
width: 200px;
|
122
|
+
padding: 10px 10px 10px 20px;
|
123
|
+
background: #efffb1;
|
124
|
+
border: solid 1px #ccd136;
|
125
|
+
margin: 0 0 10px 15px;
|
126
|
+
}*/
|
127
|
+
|
128
|
+
|
129
|
+
|
130
|
+
#toc {
|
131
|
+
position: fixed;
|
132
|
+
top: 20px;
|
133
|
+
background: none;
|
134
|
+
border: none;
|
135
|
+
right: 20px;
|
136
|
+
border-left: solid 5px #ddd;
|
137
|
+
width: 260px;
|
138
|
+
/* bottom: 20px;*/
|
139
|
+
height: 100%;
|
140
|
+
-webkit-box-sizing: border-box;
|
141
|
+
-moz-box-sizing: border-box;
|
142
|
+
}
|
143
|
+
#toc li {
|
144
|
+
padding: 5px;
|
145
|
+
}
|
146
|
+
#toc a {
|
147
|
+
background: #efffb1;
|
148
|
+
}
|
149
|
+
a.toc-top-link {
|
150
|
+
-moz-background-clip:border;
|
151
|
+
-moz-background-inline-policy:continuous;
|
152
|
+
-moz-background-origin:padding;
|
153
|
+
background:#EEEEEE none repeat scroll 0 0;
|
154
|
+
font-size:8pt;
|
155
|
+
left:-40px;
|
156
|
+
padding:4px;
|
157
|
+
position:absolute;
|
158
|
+
text-align:center;
|
159
|
+
top:5px;
|
160
|
+
width:30px;
|
161
|
+
}
|
data/lib/docapi.rb
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'tempfile'
|
3
|
+
require 'maruku'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
class Docapi
|
7
|
+
|
8
|
+
FILES_TO_INCLUDE = {
|
9
|
+
:javascripts => ["./javascripts/documentation/highlight.pack.js", "./javascripts/documentation/jquery-1.3.2.min.js", "./javascripts/documentation/jquery.tableofcontents.min.js", "./javascripts/documentation/documentation.js"],
|
10
|
+
:stylesheets => ["./stylesheets/documentation/layout.css", "./stylesheets/documentation/syntax.css", "./stylesheets/documentation/highlighter/default.css"]
|
11
|
+
}
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
def merge(input_path, output_path, options = {})
|
18
|
+
input_dir = Pathname.new(input_path)
|
19
|
+
raise ArgumentError, "Input directory does not exist" unless input_dir.directory?
|
20
|
+
output_dir = Pathname.new(output_path || Pathname.getwd+"generated-doc")
|
21
|
+
output_dir.mkpath
|
22
|
+
output = File.open(output_dir+"index.html", "w+")
|
23
|
+
output << header(:title => options[:title])
|
24
|
+
output << convert_directory(input_dir)
|
25
|
+
output << footer
|
26
|
+
output.close
|
27
|
+
# copy stylesheets and javascripts files
|
28
|
+
FileUtils.cp_r(File.join(File.dirname(__FILE__), "..", "files", "."), output_dir)
|
29
|
+
end
|
30
|
+
|
31
|
+
def convert_directory(dir, level = 1)
|
32
|
+
output = []
|
33
|
+
dir.entries.each do |entry|
|
34
|
+
next if entry.to_s =~ /^\./
|
35
|
+
path = dir+entry
|
36
|
+
title = File.basename(entry).gsub(/\d+-/, "").gsub(/\..+?$/, "")
|
37
|
+
output << "<div class='docapi-section #{title.downcase}'>"
|
38
|
+
if path.directory?
|
39
|
+
output << "<h#{level}>#{title.capitalize}</h#{level}>"
|
40
|
+
output << convert_directory(path, level+1)
|
41
|
+
else
|
42
|
+
output << convert_file(path)
|
43
|
+
end
|
44
|
+
output << '</div>'
|
45
|
+
end
|
46
|
+
output.flatten
|
47
|
+
end
|
48
|
+
|
49
|
+
def convert_file(file)
|
50
|
+
case file.extname
|
51
|
+
when ".md"
|
52
|
+
Maruku.new( File.read(file) ).to_html
|
53
|
+
when ".rb"
|
54
|
+
process_file_sections(file, 'ruby', [/^=begin (.*)$/, /^=end$/])
|
55
|
+
when ".py"
|
56
|
+
process_file_sections(file, 'python', [/^''' (.*)$/, /^'''$/])
|
57
|
+
when ".sh"
|
58
|
+
process_file_sections(file, 'bash', [/^<<ENDCOMMENT >\/dev\/null$/, /^ENDCOMMENT$/])
|
59
|
+
when ".html"
|
60
|
+
File.read(file)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
def process_file_sections(file, language, regexps)
|
66
|
+
blocks = []
|
67
|
+
output = ["<div class='docapi-subsection'><div class='docapi-title'>#{File.basename(file).gsub(/^\d+-/, "")}</div>"]
|
68
|
+
File.open(file, "r").each do |line|
|
69
|
+
if line =~ regexps.first
|
70
|
+
output << write_block(blocks.pop)
|
71
|
+
blocks << {:content => "", :language => ($1 || "markdown")}
|
72
|
+
elsif line =~ regexps.last
|
73
|
+
output << write_block(blocks.pop)
|
74
|
+
else
|
75
|
+
blocks << {:content => "", :language => language} if blocks.last.nil?
|
76
|
+
blocks.last[:content] << line
|
77
|
+
end
|
78
|
+
end
|
79
|
+
output << write_block(blocks.pop)
|
80
|
+
output << '</div>'
|
81
|
+
end
|
82
|
+
|
83
|
+
def write_block(block)
|
84
|
+
if block
|
85
|
+
case block[:language]
|
86
|
+
when "markdown", "text"
|
87
|
+
Maruku.new( block[:content] ).to_html.gsub(/<pre class='(.+?)'><code>(.*?)<\/code><\/pre>/m, '<pre><code class="\1">\2</code></pre>')
|
88
|
+
else
|
89
|
+
'<pre><code class="'+block[:language]+'">'+block[:content]+'</code></pre>'
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def generate(input_paths, output_path, options = {})
|
95
|
+
require 'rdoc'
|
96
|
+
require 'rdoc/rdoc'
|
97
|
+
rdoc_options = %w{-f html --one-file --charset=UTF-8 -U}
|
98
|
+
rdoc_options.concat input_paths
|
99
|
+
output_dir = Pathname.new(output_path || Pathname.getwd+"documentation")
|
100
|
+
raise ArgumentError, "Output directory '#{output_dir}' does not exist" unless output_dir.directory?
|
101
|
+
rdoc_output = Tempfile.new("rdoc_output.html")
|
102
|
+
old_stdout = $stdout
|
103
|
+
begin
|
104
|
+
# redirect stdout to the file
|
105
|
+
$stdout = rdoc_output
|
106
|
+
RDoc::RDoc.new.document(rdoc_options)
|
107
|
+
ensure
|
108
|
+
$stdout = old_stdout
|
109
|
+
end
|
110
|
+
rdoc_output.rewind
|
111
|
+
documentation = rdoc_output.read
|
112
|
+
rdoc_output.close
|
113
|
+
date = documentation[/<tr><td>Modified:<\/td><td>(.*?)<\/td><\/tr>/, 1]
|
114
|
+
methods = documentation.split("<h4> method: ")
|
115
|
+
methods.shift
|
116
|
+
methods.map!{ |m|
|
117
|
+
["<div class='docapi-subsection'>", m.gsub(/<blockquote><pre>.*/m, "").gsub(/<a name="(.+?)">(.*?)<br \/>\s*?<\/a>/m, "<div class='docapi-title'><a name=\"\\1\">\\2<a></div>").gsub(/<h2>(.*?)<\/h2>/m, "<div class='docapi-subtitle'>\\1</div>").gsub(/<pre>(.*?)<\/pre>/m, "<pre><code>\\1</code></pre>"), "</div>"].join("")
|
118
|
+
}
|
119
|
+
|
120
|
+
File.open(File.join(output_dir.realpath, "documentation.html"), "w+") do |f|
|
121
|
+
# sort methods by :call-seq: length ASC. A bit dirty but...
|
122
|
+
methods.sort_by{|m| method = m[/<div class='docapi-title'><a name=".*?">(.+?)<a><\/div>/, 1].length rescue 0}.each{ |method| f << method }
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
def header(options = {})
|
128
|
+
output = []
|
129
|
+
output << "<html><head><title>#{options[:title] || "Documentation"}</title>"
|
130
|
+
FILES_TO_INCLUDE[:javascripts].each do |file|
|
131
|
+
output << '<script type="text/javascript" src="'+file+'"></script>'
|
132
|
+
end
|
133
|
+
FILES_TO_INCLUDE[:stylesheets].each do |file|
|
134
|
+
output << '<link media="screen" type="text/css" href="'+file+'" rel="stylesheet"/>'
|
135
|
+
end
|
136
|
+
output << %Q{
|
137
|
+
<!--[if IE]>
|
138
|
+
<style type="text/css" media="screen">
|
139
|
+
body {padding-right: 320px}
|
140
|
+
</style>
|
141
|
+
<![endif]-->}
|
142
|
+
output << "</head><body>"
|
143
|
+
end
|
144
|
+
def footer
|
145
|
+
output = []
|
146
|
+
output << "<div id='generation-date'>Generated at: <span class='date'>#{Time.now.to_s}</span></div>"
|
147
|
+
output << "</body></html>"
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
|
3
|
+
module API
|
4
|
+
class ReferenceAPI < Sinatra::Base
|
5
|
+
|
6
|
+
##
|
7
|
+
# :method: get(/:grid5000-resource/versions[.:format])
|
8
|
+
#
|
9
|
+
# :call-seq:
|
10
|
+
# GET /:grid5000-resource/versions[.:format]
|
11
|
+
#
|
12
|
+
# Get the list of all versions of a particular resource.
|
13
|
+
#
|
14
|
+
# == URI parameters
|
15
|
+
# <tt>grid5000-resource</tt>:: the URI of the grid5000 resource.
|
16
|
+
# <tt>format</tt>:: the requested format [json,xml] if you do not use the <tt>Accept</tt> header in your HTTP request.
|
17
|
+
#
|
18
|
+
# == Query parameters
|
19
|
+
# <tt>limit</tt>:: maximum number of versions to return.
|
20
|
+
#
|
21
|
+
# == Content-Types
|
22
|
+
# <tt>application/json</tt>:: JSON
|
23
|
+
# <tt>application/xml</tt>:: XML
|
24
|
+
#
|
25
|
+
# == Status codes
|
26
|
+
# <tt>200</tt>:: OK, the response contains the list of the versions of the requested grid5000 resource.
|
27
|
+
# <tt>404</tt>:: the requested grid5000 resource cannot be found.
|
28
|
+
# <tt>406</tt>:: the requested format is not available.
|
29
|
+
#
|
30
|
+
# == Usage
|
31
|
+
# Get the 2 latest versions of the Rennes site:
|
32
|
+
# GET /grid5000/sites/rennes/versions?limit=2 HTTP/1.1
|
33
|
+
# Accept: application/json
|
34
|
+
#
|
35
|
+
#
|
36
|
+
# HTTP/1.1 200 OK
|
37
|
+
# Date: Tue, 17 Mar 2009 13:41:45 GMT
|
38
|
+
# ETag: "0745dc6351cdd00919e8611f8f6952eb48fc9b56"
|
39
|
+
# Cache-Control: public, max-age=120
|
40
|
+
# Age: 0
|
41
|
+
# Content-Length: 496
|
42
|
+
# Content-Type: application/json;charset=utf-8
|
43
|
+
# [
|
44
|
+
# {
|
45
|
+
# "message": "Added network interfaces to helios and azur clusters.",
|
46
|
+
# "uri": "\/sites\/versions\/29202872636a3f4023b956cc7bba38c15850ec9f",
|
47
|
+
# "date": "Tue, 17 Mar 2009 09:28:27 GMT",
|
48
|
+
# "id": "29202872636a3f4023b956cc7bba38c15850ec9f"
|
49
|
+
# },
|
50
|
+
# {
|
51
|
+
# "message": "Added network interfaces to genepi nodes.",
|
52
|
+
# "uri": "\/sites\/versions\/7edfbafddb08beb8251c543c5c96e5d736bf23fa",
|
53
|
+
# "date": "Tue, 17 Mar 2009 09:17:48 GMT",
|
54
|
+
# "id": "7edfbafddb08beb8251c543c5c96e5d736bf23fa"
|
55
|
+
# }
|
56
|
+
# ]
|
57
|
+
#
|
58
|
+
|
59
|
+
#
|
60
|
+
get '*/versions.:format' do |resource_uri, format|
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
##
|
65
|
+
# :method: get(/:grid5000-resource/versions/:version[.:format])
|
66
|
+
#
|
67
|
+
# :call-seq:
|
68
|
+
# GET /:grid5000-resource/versions/:version[.:format]
|
69
|
+
#
|
70
|
+
# Get info about a specific version.
|
71
|
+
#
|
72
|
+
# == URI parameters
|
73
|
+
# <tt>grid5000-resource</tt>:: the URI of the grid5000 resource.
|
74
|
+
# <tt>version</tt>:: the version id (40 characters long) or a UNIX timestamp.
|
75
|
+
#
|
76
|
+
# == Content-Types
|
77
|
+
# <tt>application/json</tt>:: JSON
|
78
|
+
# <tt>application/xml</tt>:: XML
|
79
|
+
#
|
80
|
+
# == Status codes
|
81
|
+
# <tt>200</tt>:: OK.
|
82
|
+
# <tt>404</tt>:: the requested grid5000 resource cannot be found, or the requested version does not exist.
|
83
|
+
# <tt>406</tt>:: the requested format is not available.
|
84
|
+
#
|
85
|
+
|
86
|
+
#
|
87
|
+
get '*/versions/:version.:format' do |resource_uri, version, format|
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
##
|
92
|
+
# :method: get(/:grid5000-resource[.:format])
|
93
|
+
#
|
94
|
+
# :call-seq:
|
95
|
+
# GET /:grid5000-resource[.:format]
|
96
|
+
#
|
97
|
+
# Get a specific version of a Grid5000 resource.
|
98
|
+
#
|
99
|
+
# == URI parameters
|
100
|
+
# <tt>grid5000-resource</tt>:: the URI of the grid5000 resource.
|
101
|
+
#
|
102
|
+
# == Query parameters
|
103
|
+
# <tt>version</tt>:: the requested version. It can be a version id (40 characters),
|
104
|
+
# or a UNIX timestamp [default=empty (most recent version is used)].
|
105
|
+
# <tt>depth</tt>:: the number of nested sub-resources to resolve [default=1].
|
106
|
+
# <tt>resolve</tt>:: a list of comma separated sub-resources names to resolve (to be used with the +depth+ parameter) [default=all].
|
107
|
+
#
|
108
|
+
# == Content-Types
|
109
|
+
# <tt>application/json</tt>:: JSON
|
110
|
+
# <tt>application/xml</tt>:: XML
|
111
|
+
# <tt>application/zip</tt>:: the ZIP format will return a zip archive containing the set of directories and files corresponding to the required data, with all its sub-resources.
|
112
|
+
#
|
113
|
+
# == Status codes
|
114
|
+
# <tt>200</tt>:: OK, the response contains the description of the resource as it was at the requested version.
|
115
|
+
# <tt>404</tt>:: the requested grid5000 resource cannot be found, or the requested version does not exist.
|
116
|
+
# <tt>406</tt>:: Returns 406 if the requested format is not available.
|
117
|
+
#
|
118
|
+
|
119
|
+
#
|
120
|
+
get '*.:format' do |resource_uri, format|
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
private
|
125
|
+
|
126
|
+
def metadata_for_commit(commit, resource_uri)
|
127
|
+
{
|
128
|
+
'uid' => commit.id,
|
129
|
+
'date' => commit.committed_date.httpdate,
|
130
|
+
'message' => commit.message,
|
131
|
+
'author' => commit.author,
|
132
|
+
'type' => 'version',
|
133
|
+
'links' => [
|
134
|
+
{'rel' => 'self', 'href' => "#{resource_uri}/versions/#{commit.id}"},
|
135
|
+
{'rel' => 'parent', 'href' => "#{resource_uri}?version=#{commit.id}"}
|
136
|
+
]
|
137
|
+
}
|
138
|
+
end
|
139
|
+
|
140
|
+
end # class ReferenceAPI
|
141
|
+
end # module API
|