cryx-g5k 0.1.0

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,47 @@
1
+ module G5K
2
+ module Parsing
3
+ class UnsupportedFormat < StandardError; end
4
+ class Parser
5
+ @@parsers = []
6
+ def self.add(*parsers)
7
+ parsers.each{ |parser|
8
+ parser.dependencies
9
+ @@parsers << parser
10
+ }
11
+ self
12
+ end
13
+ def self.select(parser_format)
14
+ raise UnsupportedFormat, "The format cannot be nil." if parser_format.nil?
15
+ parsers = @@parsers.select{|parser| parser.supported_formats.include?(parser_format.to_sym)}
16
+ if parsers.empty?
17
+ raise UnsupportedFormat, "No parser found for '#{parser_format}' format."
18
+ else
19
+ parsers.first
20
+ end
21
+ end
22
+ def self.available_parsers; @@parsers; end
23
+ end
24
+
25
+ class JSONParser
26
+ def self.dependencies
27
+ require 'json'
28
+ end
29
+ def self.supported_formats
30
+ [:json]
31
+ end
32
+ def self.dump(object, options = {:format => :pretty})
33
+ case options[:format]
34
+ when :pretty
35
+ JSON.pretty_generate object
36
+ else
37
+ object.to_json
38
+ end
39
+ end
40
+ def self.load(object)
41
+ JSON.parse(object)
42
+ end
43
+ end
44
+
45
+ # Parser.add(JSONParser)
46
+ end
47
+ end
@@ -0,0 +1,7 @@
1
+ require File.dirname(__FILE__)+'/parsing/parser.rb'
2
+
3
+ module G5K
4
+ module Parsing
5
+ VERSION = 0.1
6
+ end
7
+ end
@@ -0,0 +1,46 @@
1
+ module G5K
2
+ module Rack
3
+ #
4
+ # A Rack middleware for automatically adding a <tt>format</tt> token at the end of the request path
5
+ # when there is none. It can detect formats passed in the HTTP_ACCEPT header to populate this token.
6
+ #
7
+ # e.g.:
8
+ # GET /some/resource HTTP/1.1
9
+ # Accept: application/json
10
+ # ->
11
+ # GET /some/resource.json HTTP/1.1
12
+ # Accept: application/json
13
+ #
14
+ # You can add custom types with this kind of function (taken from sinatra):
15
+ # def mime(ext, type)
16
+ # ext = ".#{ext}" unless ext.to_s[0] == ?.
17
+ # Rack::Mime::MIME_TYPES[ext.to_s] = type
18
+ # end
19
+ # and then:
20
+ # mime :json, 'application/json'
21
+ #
22
+ # Note: it does not take into account multiple media types in the Accept header.
23
+ # The first media type takes precedence over all the others.
24
+ #
25
+ # MIT-License - Cyril Rohr
26
+ #
27
+ class AcceptFormat
28
+ # Constants
29
+ DEFAULT_EXTENSION = ".html"
30
+
31
+ def initialize(app)
32
+ @app = app
33
+ end
34
+
35
+ def call(env)
36
+ req = Rack::Request.new(env)
37
+ unless req.path_info =~ /(.*)\.(.+)/
38
+ accept = env['HTTP_ACCEPT'].scan(/[^;,\s]*\/[^;,\s]*/)[0] rescue ""
39
+ extension = Rack::Mime::MIME_TYPES.invert[accept] || DEFAULT_EXTENSION
40
+ req.path_info = req.path_info+"#{extension}"
41
+ end
42
+ @app.call(env)
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,43 @@
1
+ module G5K
2
+ module Rack
3
+
4
+ # A Rack middleware for providing JSON-P support.
5
+ #
6
+ # Full credit to Flinn Mueller (http://actsasflinn.com/) for this contribution.
7
+ #
8
+ class JSONP
9
+
10
+ def initialize(app)
11
+ @app = app
12
+ end
13
+
14
+ # Proxies the request to the application, stripping out the JSON-P callback
15
+ # method and padding the response with the appropriate callback format.
16
+ #
17
+ # Changes nothing if no <tt>callback</tt> param is specified.
18
+ #
19
+ def call(env)
20
+ status, headers, response = @app.call(env)
21
+ request = Rack::Request.new(env)
22
+ if request.params.include?('callback')
23
+ response = pad(request.params.delete('callback'), response)
24
+ headers['Content-Length'] = response.length.to_s
25
+ end
26
+ [status, headers, response]
27
+ end
28
+
29
+ # Pads the response with the appropriate callback format according to the
30
+ # JSON-P spec/requirements.
31
+ #
32
+ # The Rack response spec indicates that it should be enumerable. The method
33
+ # of combining all of the data into a single string makes sense since JSON
34
+ # is returned as a full string.
35
+ #
36
+ def pad(callback, response, body = "")
37
+ response.each{ |s| body << s }
38
+ "#{callback}(#{body})"
39
+ end
40
+
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,32 @@
1
+ module G5K
2
+ module Sinatra
3
+ module Helpers
4
+ def returning(thing = nil)
5
+ yield thing
6
+ thing
7
+ end
8
+
9
+ def provides *formats
10
+ if params[:format].nil? || !formats.include?(params[:format].to_sym)
11
+ throw :halt, [406, "The accepted types are: #{formats.join(", ")}"]
12
+ end
13
+ end
14
+
15
+ def formatted_error(http_status, options = {})
16
+ body = {:code => (options[:code] || http_status), :message => options[:message], :title => options[:title]}
17
+ format = options[:format] || params[:format] || "txt"
18
+ content_type format.to_sym, :charset => 'utf-8'
19
+ if (parser = Parser.select(format.to_sym))
20
+ body = parser.dump(body)
21
+ else
22
+ body.map!{|(k,v)| [k,v].join("=")}.join(";")
23
+ end
24
+ error(http_status, body)
25
+ end
26
+
27
+ def compute_etag(*differentiators)
28
+ Digest::SHA1.hexdigest(differentiators.join("."))
29
+ end
30
+ end
31
+ end
32
+ end
data/lib/g5k.rb ADDED
@@ -0,0 +1,5 @@
1
+ # Subdirs are not automatically loaded. Users must explicitly require them.
2
+
3
+ module G5K
4
+
5
+ end
data/spec/g5k_spec.rb ADDED
@@ -0,0 +1,4 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe "G5k" do
4
+ end
@@ -0,0 +1,44 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+ require File.dirname(__FILE__) + '/../lib/g5k/parsing'
3
+
4
+ include G5K::Parsing
5
+ describe "Parsing" do
6
+ before do
7
+ require 'rubygems'
8
+ end
9
+ it "should add the json parser" do
10
+ Parser.add(JSONParser).available_parsers.should include(JSONParser)
11
+ end
12
+ it "should return an error if a parser is not available for the required format" do
13
+ Parser.add(JSONParser)
14
+ lambda{Parser.select(:xml)}.should raise_error(UnsupportedFormat)
15
+ end
16
+ it "should raise an UnsupportedFormat if the given format is nil" do
17
+ lambda{Parser.select(nil)}.should raise_error(UnsupportedFormat)
18
+ end
19
+ it "should select the parser for the given format, if made available" do
20
+ Parser.add(JSONParser)
21
+ Parser.select(:json).should == JSONParser
22
+ end
23
+ end
24
+
25
+ describe JSONParser do
26
+ before do
27
+ require 'rubygems'
28
+ end
29
+ it "should successfully parse a json object" do
30
+ object = {'a' => 1, 'b' => {'c' => 2, 'd' => [3]}}
31
+ JSONParser.load(object.to_json).should == object
32
+ end
33
+ it "should pretty generate an object" do
34
+ object = {'a' => 1, 'b' => {'c' => 2, 'd' => [3]}}
35
+ JSON.should_receive(:pretty_generate).with(object)
36
+ JSONParser.dump(object, :format => :pretty)
37
+ end
38
+ it "should not pretty generate an object" do
39
+ object = {'a' => 1, 'b' => {'c' => 2, 'd' => [3]}}
40
+ JSON.should_not_receive(:pretty_generate).with(object)
41
+ object.should_receive(:to_json)
42
+ JSONParser.dump(object, :format => :raw)
43
+ end
44
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec'
2
+
3
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
4
+
5
+ require File.dirname(__FILE__) + '/../lib/g5k'
6
+
7
+ Spec::Runner.configure do |config|
8
+
9
+ end
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cryx-g5k
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Cyril Rohr
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-03-02 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Collection of tools and libs for Grid5000 APIs.
17
+ email: cyril.rohr@irisa.fr
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - VERSION.yml
26
+ - lib/g5k
27
+ - lib/g5k/parsing
28
+ - lib/g5k/parsing/parser.rb
29
+ - lib/g5k/parsing.rb
30
+ - lib/g5k/rack
31
+ - lib/g5k/rack/accept_format.rb
32
+ - lib/g5k/rack/jsonp.rb
33
+ - lib/g5k/schema
34
+ - lib/g5k/sinatra
35
+ - lib/g5k/sinatra/helpers.rb
36
+ - lib/g5k.rb
37
+ - spec/g5k_spec.rb
38
+ - spec/parsing_spec.rb
39
+ - spec/spec_helper.rb
40
+ has_rdoc: true
41
+ homepage: http://github.com/cryx/g5k
42
+ post_install_message:
43
+ rdoc_options:
44
+ - --inline-source
45
+ - --charset=UTF-8
46
+ require_paths:
47
+ - lib
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: "0"
53
+ version:
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: "0"
59
+ version:
60
+ requirements: []
61
+
62
+ rubyforge_project:
63
+ rubygems_version: 1.2.0
64
+ signing_key:
65
+ specification_version: 2
66
+ summary: TODO
67
+ test_files: []
68
+