marley 0.2.0 → 0.3.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.
- data/lib/marley.rb +27 -3
- data/lib/marley/controllers.rb +1 -0
- data/lib/marley/joint.rb +4 -0
- data/lib/marley/reggae.rb +33 -35
- data/lib/sequel/plugins/rest_convenience.rb +1 -1
- data/marley.gemspec +1 -1
- data/test/test.sqlite3 +0 -0
- metadata +2 -3
- data/marley-0.1.0.gem +0 -0
data/lib/marley.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
#!/usr/bin/ruby
|
2
2
|
require 'json/ext'
|
3
|
+
require 'json/add/core'
|
3
4
|
require 'rack'
|
4
5
|
require 'rack/auth/basic'
|
5
6
|
require 'rack/builder'
|
@@ -19,29 +20,52 @@ Sequel::Model.plugin :timestamps, :create => :date_created, :update => :date_upd
|
|
19
20
|
log_fn='log/marley.log'
|
20
21
|
$log=Logger.new(File.exists?(log_fn) ? log_fn : $stdout)
|
21
22
|
|
22
|
-
|
23
|
-
module Marley
|
23
|
+
# This is the main Marley namespace
|
24
|
+
module Marley
|
24
25
|
JOINT_DIRS=[File.expand_path("joints/",File.dirname(__FILE__)),"#{Dir.pwd}/joints"]
|
26
|
+
# @see config
|
25
27
|
DEFAULT_OPTS={:http_auth => true,:app_name => 'Application',:port => 1620,:default_user_class => :User, :auth_class => :User,:default_resource => 'Menu', :server => 'thin'}
|
26
28
|
RESP_CODES={'get' => 200,'post' => 201,'put' => 204,'delete' => 204}
|
27
29
|
|
28
|
-
|
30
|
+
# All constants in the Resources namespace should refer to public resources accessible to clients, subject, of course, to authentication/authorization.
|
31
|
+
#
|
32
|
+
# Resources MUST respond to one or more of #controller, #rest_get, #rest_post, #rest_put, #rest_delete
|
33
|
+
#
|
34
|
+
# If a Resource implements a #controller method, the method MUST return an object which responds to one or more of #rest_get, #rest_post, #rest_put, #rest_delete
|
35
|
+
module Resources
|
29
36
|
end
|
37
|
+
# The default namespace for Joints. Joints MUST implement a #smoke method
|
30
38
|
module Joints
|
31
39
|
end
|
32
40
|
require 'marley/joint' #this needs to happen after Marley::Resources is defined
|
41
|
+
|
42
|
+
# Override default Marley configuration
|
43
|
+
# @param [Hash] opts A hash containing Marley configuration options
|
44
|
+
# @option opts [Boolean] :http_auth Whether or not to use http authentication
|
45
|
+
# @option opts [String] :app_name Currently used by Jamaica to set page title
|
46
|
+
# @option opts [Number] :port Port on which to run the server
|
47
|
+
# @option opts [Object] :default_user_class The default class of the new user assigned to $request[:user] if no actual user is authenticated
|
48
|
+
# @option opts [Object] :auth_class The class used to authenticate requests. MUST respond to #authenticate
|
49
|
+
# @option opts [Object] :default_resource The resource called in response to a request to '/'
|
50
|
+
# @option opts [String] :server the Rack web server to be used.
|
33
51
|
def self.config(opts=nil)
|
34
52
|
@marley_opts||=DEFAULT_OPTS
|
35
53
|
@marley_opts.merge!(opts) if opts
|
36
54
|
yield @marley_opts if block_given?
|
37
55
|
@marley_opts
|
38
56
|
end
|
57
|
+
|
58
|
+
# Loads a joint and and calls its #smoke method
|
59
|
+
# @param [String] joint_name The name of the joint to load and smoke - additional paramters passed through to the joint itself
|
39
60
|
def self.joint(joint_name, *opts)
|
40
61
|
joint_d=JOINT_DIRS.find {|d| File.exists?("#{d}/#{joint_name}.rb") }
|
41
62
|
require "#{joint_d}/#{joint_name}"
|
42
63
|
@marley_opts && @marley_opts[:client] && @marley_opts[:client].joint(joint_d,joint_name)
|
43
64
|
joint=Marley::Joints.const_get(joint_name.camelize).new(*opts).smoke
|
44
65
|
end
|
66
|
+
|
67
|
+
# Runs the server
|
68
|
+
# @param (see #config)
|
45
69
|
def self.run(opts={})
|
46
70
|
@marley_opts||=DEFAULT_OPTS
|
47
71
|
marley_opts=@marley_opts.merge!(opts)
|
data/lib/marley/controllers.rb
CHANGED
data/lib/marley/joint.rb
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
module Marley
|
2
2
|
module Joints
|
3
|
+
# @abstract Subclass and implement one or more of the following modules within the class namespace:
|
4
|
+
# - Resources - All constansts in this module will be imported into Marley::Resources
|
5
|
+
# - ClassMethods - Modules within this module will extend any constant in Marley::Resources with the same name.
|
6
|
+
# - InstanceMethods - Modules within this module will append their features to any constant in Marley::Resources with the same name.
|
3
7
|
class Joint
|
4
8
|
def initialize(opts={})
|
5
9
|
config(opts)
|
data/lib/marley/reggae.rb
CHANGED
@@ -1,10 +1,14 @@
|
|
1
1
|
|
2
2
|
module Marley
|
3
|
+
# @see file:reggae.ebnf for Raggae sytax
|
3
4
|
class Reggae < Array
|
4
5
|
class << self
|
5
|
-
|
6
|
+
def properties(*args)
|
7
|
+
@properties=args if args
|
8
|
+
@properties
|
9
|
+
end
|
6
10
|
def mk_prop_methods
|
7
|
-
@
|
11
|
+
@properties && @properties.each do |meth|
|
8
12
|
define_method(meth) {properties[meth].respond_to?(:to_resource) ? properties[meth].to_resource : properties[meth]}
|
9
13
|
define_method(:"#{meth}=") {|val|properties[meth]=val}
|
10
14
|
end
|
@@ -13,30 +17,28 @@ module Marley
|
|
13
17
|
self.new(*args).to_resource
|
14
18
|
end
|
15
19
|
end
|
20
|
+
attr_reader :resource_type
|
21
|
+
attr_accessor :properties,:contents
|
22
|
+
# @param [Array] *args an array in Reggae syntax
|
16
23
|
def initialize(*args)
|
17
24
|
super
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
25
|
+
if is_resource?
|
26
|
+
@resource_type=self[0]=self[0].to_sym
|
27
|
+
self[1]=Utils.hash_keys_to_syms(self[1]) if self[1].class==Hash
|
28
|
+
@properties=self[1]
|
29
|
+
@contents=self[2 .. -1]
|
30
|
+
self.class.mk_prop_methods
|
31
|
+
else
|
32
|
+
replace(map {|r| Reggae.new(r).to_resource})
|
33
|
+
end
|
26
34
|
end
|
27
35
|
def is_resource?
|
28
|
-
|
29
|
-
end
|
30
|
-
def contents
|
31
|
-
is_resource? ? Reggae.new(self[2 .. -1]) : nil
|
36
|
+
[String, Symbol].include?(self[0].class) && self[1].class==Hash
|
32
37
|
end
|
33
38
|
def contents=(*args)
|
34
39
|
self[2]=*args
|
35
40
|
while length>3;delete_at -1;end
|
36
41
|
end
|
37
|
-
def [](*args)
|
38
|
-
super.class==Array ? Reggae.new(super).to_resource : super
|
39
|
-
end
|
40
42
|
def to_resource
|
41
43
|
is_resource? ? Marley.const_get("Reggae#{resource_type.to_s.camelize}".to_sym).new(self) : self
|
42
44
|
end
|
@@ -50,34 +52,34 @@ module Marley
|
|
50
52
|
end
|
51
53
|
end
|
52
54
|
class ReggaeResource < Reggae
|
53
|
-
def resource_type
|
54
|
-
self.class.to_s.sub(/.*Reggae/,'').underscore.to_sym
|
55
|
-
end
|
56
55
|
def initialize(*args)
|
56
|
+
@resource_type=self.class.to_s.sub(/.*Reggae/,'').underscore.to_sym
|
57
57
|
if args[0].class==Hash
|
58
|
-
initialize [resource_type,args[0]]
|
58
|
+
initialize [@resource_type,args[0]]
|
59
59
|
else
|
60
60
|
super
|
61
61
|
end
|
62
62
|
end
|
63
63
|
end
|
64
64
|
class ReggaeSection < ReggaeResource
|
65
|
-
|
65
|
+
properties :title,:description
|
66
66
|
def navigation
|
67
67
|
properties[:navigation].map{|n|Reggae.get_resource(n)}
|
68
68
|
end
|
69
69
|
end
|
70
70
|
class ReggaeLink < ReggaeResource
|
71
|
-
|
71
|
+
properties :title,:description,:url
|
72
72
|
end
|
73
73
|
class ReggaeInstance < ReggaeResource
|
74
|
-
|
74
|
+
properties :name,:new_rec,:schema,:search,:url,:get_actions,:delete_action
|
75
|
+
attr_accessor :schema
|
75
76
|
def initialize(*args)
|
76
77
|
super
|
77
|
-
|
78
|
+
@properties[:schema]=ReggaeSchema.new(self.schema)
|
79
|
+
@schema=@properties[:schema]
|
78
80
|
end
|
79
81
|
def to_params
|
80
|
-
schema.inject({}) do |params,spec|
|
82
|
+
@schema.inject({}) do |params,spec|
|
81
83
|
params["#{name}[#{spec.col_name}]"]=spec.col_value unless (spec.col_restrictions & RESTRICT_RO > 0)
|
82
84
|
params
|
83
85
|
end
|
@@ -86,7 +88,7 @@ module Marley
|
|
86
88
|
"#{url}#{action_name}" if get_actions.include?(action_name.to_s)
|
87
89
|
end
|
88
90
|
def col_value(col_name,col_value=nil)
|
89
|
-
col
|
91
|
+
col=@schema[col_name]
|
90
92
|
col.col_value=col_value if col_value
|
91
93
|
col.col_value
|
92
94
|
end
|
@@ -96,14 +98,14 @@ module Marley
|
|
96
98
|
end
|
97
99
|
end
|
98
100
|
class ReggaeInstanceList < ReggaeResource
|
99
|
-
|
101
|
+
properties :name,:description,:get_actions,:delete_action,:items
|
100
102
|
#not implemented yet
|
101
103
|
end
|
102
104
|
class ReggaeMsg < ReggaeResource
|
103
|
-
|
105
|
+
properties :title,:description
|
104
106
|
end
|
105
107
|
class ReggaeError < ReggaeResource
|
106
|
-
|
108
|
+
properties :error_type,:description,:error_details
|
107
109
|
end
|
108
110
|
class ReggaeSchema < Array
|
109
111
|
def initialize(*args)
|
@@ -111,11 +113,7 @@ module Marley
|
|
111
113
|
replace(map{|spec| ReggaeColSpec.new(spec)})
|
112
114
|
end
|
113
115
|
def [](i)
|
114
|
-
|
115
|
-
super
|
116
|
-
else
|
117
|
-
find {|cs|cs.col_name.to_s==i.to_s}
|
118
|
-
end
|
116
|
+
i.class==Fixnum ? super : find {|cs|cs.col_name.to_s==i.to_s}
|
119
117
|
end
|
120
118
|
end
|
121
119
|
class ReggaeColSpec < Array
|
@@ -70,7 +70,7 @@ module Sequel::Plugins::RestConvenience
|
|
70
70
|
respond_to?('name') ? name : id.to_s
|
71
71
|
end
|
72
72
|
def to_a
|
73
|
-
a=Marley::ReggaeInstance.new( {:name => self.class.resource_name,:url => url ,:new_rec => self.new?,:schema => rest_schema,:get_actions => get_actions})
|
73
|
+
a=Marley::ReggaeInstance.new( {:name => self.class.resource_name,:url => url ,:new_rec => self.new?,:schema => rest_schema,:get_actions => get_actions.class==Hash ? get_actions[$request[:user].class] : get_actions})
|
74
74
|
if respond_to?(:rest_associations) && ! new?
|
75
75
|
a.contents=rest_associations.map do |assoc|
|
76
76
|
(assoc.class==Symbol ? send(assoc) : assoc).map{|instance| instance.to_a}
|
data/marley.gemspec
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{marley}
|
5
|
-
s.version = "0.
|
5
|
+
s.version = "0.3.0"
|
6
6
|
s.summary = %q{Irie default restful routes for your models and other objects}
|
7
7
|
s.description = %q{Marley implements a web services microframework on top of Rack and Sequel on the server side and Jquery on the client side.}
|
8
8
|
s.authors = ["Herb Daily"]
|
data/test/test.sqlite3
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: marley
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Herb Daily
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2011-11-
|
12
|
+
date: 2011-11-20 00:00:00 -03:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -55,7 +55,6 @@ files:
|
|
55
55
|
- Rakefile
|
56
56
|
- Favicon.ico
|
57
57
|
- README.rdoc
|
58
|
-
- marley-0.1.0.gem
|
59
58
|
- TODO
|
60
59
|
- reggae.ebnf
|
61
60
|
- forum_tests.rb
|
data/marley-0.1.0.gem
DELETED
Binary file
|