halcyon 0.3.7
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.
- data/Rakefile +135 -0
- data/bin/halcyon +152 -0
- data/lib/halcyon.rb +54 -0
- data/lib/halcyon/client.rb +43 -0
- data/lib/halcyon/client/base.rb +236 -0
- data/lib/halcyon/client/exceptions.rb +53 -0
- data/lib/halcyon/client/router.rb +106 -0
- data/lib/halcyon/exceptions.rb +19 -0
- data/lib/halcyon/server.rb +55 -0
- data/lib/halcyon/server/base.rb +392 -0
- data/lib/halcyon/server/exceptions.rb +53 -0
- data/lib/halcyon/server/router.rb +100 -0
- data/lib/halcyon/support/hashext.rb +59 -0
- metadata +104 -0
@@ -0,0 +1,53 @@
|
|
1
|
+
#--
|
2
|
+
# Created by Matt Todd on 2007-12-14.
|
3
|
+
# Copyright (c) 2007. All rights reserved.
|
4
|
+
#++
|
5
|
+
|
6
|
+
#--
|
7
|
+
# module
|
8
|
+
#++
|
9
|
+
|
10
|
+
module Halcyon
|
11
|
+
class Server
|
12
|
+
class Base
|
13
|
+
module Exceptions #:nodoc:
|
14
|
+
|
15
|
+
#--
|
16
|
+
# Base Halcyon Exception
|
17
|
+
#++
|
18
|
+
|
19
|
+
class Base < Exception #:nodoc:
|
20
|
+
attr_accessor :status, :error
|
21
|
+
def initialize(status, error)
|
22
|
+
@status = status
|
23
|
+
@error = error
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
#--
|
28
|
+
# Exception classes
|
29
|
+
#++
|
30
|
+
|
31
|
+
Halcyon::Exceptions::HTTP_ERROR_CODES.to_a.each do |http_error|
|
32
|
+
status, body = http_error
|
33
|
+
class_eval(
|
34
|
+
"class #{body.gsub(/ /,'')} < Base\n"+
|
35
|
+
" def initialize(s=#{status}, e='#{body}')\n"+
|
36
|
+
" super s, e\n"+
|
37
|
+
" end\n"+
|
38
|
+
"end"
|
39
|
+
);
|
40
|
+
end
|
41
|
+
|
42
|
+
#--
|
43
|
+
# Exception Lookup
|
44
|
+
#++
|
45
|
+
|
46
|
+
def self.lookup(status)
|
47
|
+
self.const_get(Halcyon::Exceptions::HTTP_ERROR_CODES[status].gsub(/ /,'').to_sym)
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
#--
|
2
|
+
# Created by Matt Todd on 2007-12-14.
|
3
|
+
# Copyright (c) 2007. All rights reserved.
|
4
|
+
#++
|
5
|
+
|
6
|
+
#--
|
7
|
+
# dependencies
|
8
|
+
#++
|
9
|
+
|
10
|
+
begin
|
11
|
+
%w(rubygems merb/core_ext merb/router).each {|dep|require dep}
|
12
|
+
rescue LoadError => e
|
13
|
+
abort "Merb must be installed for Routing to function. Please install Merb."
|
14
|
+
end
|
15
|
+
|
16
|
+
#--
|
17
|
+
# module
|
18
|
+
#++
|
19
|
+
|
20
|
+
module Halcyon
|
21
|
+
class Server
|
22
|
+
|
23
|
+
# = Routing
|
24
|
+
#
|
25
|
+
# Handles routing.
|
26
|
+
#
|
27
|
+
# == Usage
|
28
|
+
#
|
29
|
+
# class Xy < Halcyon::Server::Base
|
30
|
+
# route do |r|
|
31
|
+
# r.match('/path/to/match').to(:action => 'do_stuff')
|
32
|
+
# {:action => 'not_found'} # the default route
|
33
|
+
# end
|
34
|
+
# def do_stuff(params)
|
35
|
+
# [200, {}, 'OK']
|
36
|
+
# end
|
37
|
+
# end
|
38
|
+
#
|
39
|
+
# == Default Routes
|
40
|
+
#
|
41
|
+
# Supplying a default route if none of the others match is good practice,
|
42
|
+
# but is unnecessary as the predefined route is always, automatically,
|
43
|
+
# going to contain a redirection to the +not_found+ method which already
|
44
|
+
# exists in Halcyon::Server::Base. This method is freely overwritable, and
|
45
|
+
# is recommended for those that wish to handle unroutable requests
|
46
|
+
# themselves.
|
47
|
+
#
|
48
|
+
# In order to set a different default route, simply end the call to +route+
|
49
|
+
# with a hash containing the action (and optionally the module) to run.
|
50
|
+
#
|
51
|
+
# == The Hard Work
|
52
|
+
#
|
53
|
+
# The mechanics of the router are solely from the efforts of the Merb
|
54
|
+
# community. This functionality is completely ripped right out of Merb
|
55
|
+
# and makes it functional. All credit to them, and be sure to check out
|
56
|
+
# their great framework: if Halcyon isn't quite what you need, maybe Merb
|
57
|
+
# is.
|
58
|
+
#
|
59
|
+
# http://merbivore.com/
|
60
|
+
class Router < Merb::Router
|
61
|
+
|
62
|
+
# Retrieves the last value from the +route+ call in Halcyon::Server::Base
|
63
|
+
# and, if it's a Hash, sets it to +@@default_route+ to designate the
|
64
|
+
# failover route. If +route+ is not a Hash, though, the internal default
|
65
|
+
# should be used instead (as the last returned value is probably a Route
|
66
|
+
# object returned by the +r.match().to()+ call).
|
67
|
+
#
|
68
|
+
# Used exclusively internally.
|
69
|
+
def self.default_to route
|
70
|
+
@@default_route = route.is_a?(Hash) ? route : {:action => 'not_found'}
|
71
|
+
end
|
72
|
+
|
73
|
+
# Called internally by the Halcyon::Server::Base#call method to match
|
74
|
+
# the current request against the currently defined routes. Returns the
|
75
|
+
# params list defined in the +to+ routing definition, opting for the
|
76
|
+
# default route if no match is made.
|
77
|
+
def self.route(env)
|
78
|
+
uri = env['REQUEST_URI']
|
79
|
+
|
80
|
+
# prepare request
|
81
|
+
path = (uri ? uri.split('?').first : '').sub(/\/+/, '/')
|
82
|
+
path = path[0..-2] if (path[-1] == ?/) && path.size > 1
|
83
|
+
req = Struct.new(:path, :method).new(path, env['REQUEST_METHOD'].downcase.to_sym)
|
84
|
+
|
85
|
+
# perform match
|
86
|
+
route = self.match(req, {})
|
87
|
+
|
88
|
+
# make sure a route is returned even if no match is found
|
89
|
+
if route[0].nil?
|
90
|
+
#return default route
|
91
|
+
@@default_route
|
92
|
+
else
|
93
|
+
# params (including action and module if set) for the matching route
|
94
|
+
route[1]
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# Pulled out from http://dev.rubyonrails.org/browser/trunk/activesupport/lib/active_support/core_ext/hash/keys.rb
|
2
|
+
module HashExt #:nodoc:
|
3
|
+
module Keys #:nodoc:
|
4
|
+
# Return a new hash with all keys converted to strings.
|
5
|
+
def stringify_keys
|
6
|
+
inject({}) do |options, (key, value)|
|
7
|
+
options[key.to_s] = value
|
8
|
+
options
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# Destructively convert all keys to strings.
|
13
|
+
def stringify_keys!
|
14
|
+
keys.each do |key|
|
15
|
+
unless key.class.to_s == "String" # weird hack to make the tests run when string_ext_test.rb is also running
|
16
|
+
self[key.to_s] = self[key]
|
17
|
+
delete(key)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
self
|
21
|
+
end
|
22
|
+
|
23
|
+
# Return a new hash with all keys converted to symbols.
|
24
|
+
def symbolize_keys
|
25
|
+
inject({}) do |options, (key, value)|
|
26
|
+
value = value.symbolize_keys if value.respond_to? :symbolize_keys # recursive # MT 2007-12-04
|
27
|
+
options[key.to_sym || key] = value
|
28
|
+
options
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Destructively convert all keys to symbols.
|
33
|
+
def symbolize_keys!
|
34
|
+
keys.each do |key|
|
35
|
+
unless key.is_a?(Symbol) || (new_key = key.to_sym).nil?
|
36
|
+
self[new_key] = self[key]
|
37
|
+
self[new_key].symbolize_keys! if self[new_key].respond_to? :symbolize_keys!
|
38
|
+
delete(key)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
self
|
42
|
+
end
|
43
|
+
|
44
|
+
alias_method :to_options, :symbolize_keys
|
45
|
+
alias_method :to_options!, :symbolize_keys!
|
46
|
+
|
47
|
+
# Validate all keys in a hash match *valid keys, raising ArgumentError on a mismatch.
|
48
|
+
# Note that keys are NOT treated indifferently, meaning if you use strings for keys but assert symbol
|
49
|
+
# as keys, this will fail.
|
50
|
+
# examples:
|
51
|
+
# { :name => "Rob", :years => "28" }.assert_valid_keys(:name, :age) # => raises "ArgumentError: Unknown key(s): years"
|
52
|
+
# { :name => "Rob", :age => "28" }.assert_valid_keys("name", "age") # => raises "ArgumentError: Unknown key(s): years, name"
|
53
|
+
# { :name => "Rob", :age => "28" }.assert_valid_keys(:name, :age) # => passes, raises nothing
|
54
|
+
def assert_valid_keys(*valid_keys)
|
55
|
+
unknown_keys = keys - [valid_keys].flatten
|
56
|
+
raise(ArgumentError, "Unknown key(s): #{unknown_keys.join(", ")}") unless unknown_keys.empty?
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
metadata
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: halcyon
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.7
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Matt Todd
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2007-12-16 00:00:00 -05:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rack
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 0.2.0
|
23
|
+
version:
|
24
|
+
- !ruby/object:Gem::Dependency
|
25
|
+
name: json
|
26
|
+
version_requirement:
|
27
|
+
version_requirements: !ruby/object:Gem::Requirement
|
28
|
+
requirements:
|
29
|
+
- - ">="
|
30
|
+
- !ruby/object:Gem::Version
|
31
|
+
version: 1.1.1
|
32
|
+
version:
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: merb
|
35
|
+
version_requirement:
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.4.1
|
41
|
+
version:
|
42
|
+
description: A JSON App Server Framework
|
43
|
+
email: chiology@gmail.com
|
44
|
+
executables:
|
45
|
+
- halcyon
|
46
|
+
extensions: []
|
47
|
+
|
48
|
+
extra_rdoc_files:
|
49
|
+
- lib
|
50
|
+
files:
|
51
|
+
- lib
|
52
|
+
- Rakefile
|
53
|
+
- lib/halcyon
|
54
|
+
- lib/halcyon/client
|
55
|
+
- lib/halcyon/client/base.rb
|
56
|
+
- lib/halcyon/client/exceptions.rb
|
57
|
+
- lib/halcyon/client/router.rb
|
58
|
+
- lib/halcyon/client.rb
|
59
|
+
- lib/halcyon/exceptions.rb
|
60
|
+
- lib/halcyon/server
|
61
|
+
- lib/halcyon/server/base.rb
|
62
|
+
- lib/halcyon/server/exceptions.rb
|
63
|
+
- lib/halcyon/server/router.rb
|
64
|
+
- lib/halcyon/server.rb
|
65
|
+
- lib/halcyon/support
|
66
|
+
- lib/halcyon/support/hashext.rb
|
67
|
+
- lib/halcyon.rb
|
68
|
+
has_rdoc: true
|
69
|
+
homepage: http://halcyon.rubyforge.org
|
70
|
+
post_install_message:
|
71
|
+
rdoc_options:
|
72
|
+
- --all
|
73
|
+
- --quiet
|
74
|
+
- --op
|
75
|
+
- rdoc
|
76
|
+
- --line-numbers
|
77
|
+
- --inline-source
|
78
|
+
- --title
|
79
|
+
- "\"Halcyon documentation\""
|
80
|
+
- --exclude
|
81
|
+
- "\"^(_darcs|spec|pkg)/\""
|
82
|
+
require_paths:
|
83
|
+
- lib
|
84
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: 1.8.6
|
89
|
+
version:
|
90
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: "0"
|
95
|
+
version:
|
96
|
+
requirements: []
|
97
|
+
|
98
|
+
rubyforge_project:
|
99
|
+
rubygems_version: 0.9.5
|
100
|
+
signing_key:
|
101
|
+
specification_version: 2
|
102
|
+
summary: A JSON App Server Framework
|
103
|
+
test_files: []
|
104
|
+
|