orange 0.0.5 → 0.0.6
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/orange.rb +1 -0
- data/lib/orange/cartons/asset_carton.rb +23 -0
- data/lib/orange/cartons/user_carton.rb +15 -0
- data/lib/orange/core.rb +12 -4
- data/lib/orange/middleware/access_control.rb +9 -3
- data/lib/orange/middleware/four_oh_four.rb +27 -0
- data/lib/orange/middleware/{radius.rb → radius_parser.rb} +0 -0
- data/lib/orange/middleware/static.rb +2 -2
- data/lib/orange/resources/asset_resource.rb +61 -0
- data/lib/orange/resources/mapper.rb +2 -1
- data/lib/orange/resources/not_found.rb +8 -0
- data/lib/orange/resources/radius.rb +76 -2
- data/lib/orange/resources/sitemap_resource.rb +4 -4
- data/lib/orange/resources/slices.rb +33 -0
- data/lib/orange/resources/user_resource.rb +15 -0
- data/lib/orange/stack.rb +1 -1
- data/spec/orange/core_spec.rb +7 -0
- metadata +14 -7
data/lib/orange.rb
CHANGED
@@ -3,5 +3,6 @@ $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
|
|
3
3
|
|
4
4
|
Dir.glob(File.join(libdir, 'orange', '*.rb')).each {|f| require f }
|
5
5
|
Dir.glob(File.join(libdir, 'orange', 'cartons', '*.rb')).each {|f| require f }
|
6
|
+
require File.join(libdir, 'orange', 'resources', 'model_resource.rb')
|
6
7
|
Dir.glob(File.join(libdir, 'orange', 'resources', '*.rb')).each {|f| require f }
|
7
8
|
Dir.glob(File.join(libdir, 'orange', 'middleware', '*.rb')).each {|f| require f }
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Orange
|
2
|
+
class Asset < Orange::Carton
|
3
|
+
id
|
4
|
+
admin do
|
5
|
+
title :name
|
6
|
+
text :caption
|
7
|
+
end
|
8
|
+
orange do
|
9
|
+
string :path, :length => 255
|
10
|
+
string :mime_type
|
11
|
+
string :secondary_path, :length => 255, :required => false
|
12
|
+
string :secondary_mime_type
|
13
|
+
end
|
14
|
+
|
15
|
+
def file_path
|
16
|
+
File.join('', 'assets', 'uploaded', path)
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_asset_tag
|
20
|
+
"<img src=\"#{file_path}\" />"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/orange/core.rb
CHANGED
@@ -65,16 +65,24 @@ module Orange
|
|
65
65
|
# Returns the orange library directory
|
66
66
|
# @return [String] the directory name indicating where the core file is
|
67
67
|
# located
|
68
|
-
def core_dir
|
69
|
-
|
68
|
+
def core_dir(*args)
|
69
|
+
if args
|
70
|
+
File.join((options[:core_dir] ||= File.dirname(__FILE__)), *args)
|
71
|
+
else
|
72
|
+
options[:core_dir] ||= File.dirname(__FILE__)
|
73
|
+
end
|
70
74
|
end
|
71
75
|
|
72
76
|
# Returns the directory of the currently executing file (using Dir.pwd),
|
73
77
|
# can be overriden using the option :app_dir in initialization
|
74
78
|
#
|
75
79
|
# @return [String] the directory name of the currently running application
|
76
|
-
def app_dir
|
77
|
-
|
80
|
+
def app_dir(*args)
|
81
|
+
if args
|
82
|
+
File.join((options[:app_dir] ||= Dir.pwd), *args)
|
83
|
+
else
|
84
|
+
options[:app_dir] ||= Dir.pwd
|
85
|
+
end
|
78
86
|
end
|
79
87
|
|
80
88
|
# Called by initialize after finished loading
|
@@ -17,14 +17,17 @@ module Orange::Middleware
|
|
17
17
|
|
18
18
|
def init(opts = {})
|
19
19
|
defs = {:locked => [:admin, :orange], :login => '/login', :logout => '/logout',
|
20
|
-
:handle_login => true, :openid => true, :
|
20
|
+
:handle_login => true, :openid => true, :single_user => true}
|
21
21
|
opts = opts.with_defaults!(defs)
|
22
22
|
@openid = opts[:openid]
|
23
23
|
@locked = opts[:locked]
|
24
24
|
@login = opts[:login]
|
25
25
|
@logout = opts[:logout]
|
26
26
|
@handle = opts[:handle_login]
|
27
|
-
@single = opts[:
|
27
|
+
@single = opts[:single_user]
|
28
|
+
unless @single
|
29
|
+
orange.load(Orange::UserResource.new, :users)
|
30
|
+
end
|
28
31
|
end
|
29
32
|
|
30
33
|
def packet_call(packet)
|
@@ -51,8 +54,11 @@ module Orange::Middleware
|
|
51
54
|
packet['user.id'] = false
|
52
55
|
packet.session['user.id'] = false
|
53
56
|
false
|
54
|
-
|
57
|
+
# Main_user can always log in (root access)
|
58
|
+
elsif packet['user.id'] == packet['orange.globals']['main_user']
|
55
59
|
true
|
60
|
+
else
|
61
|
+
orange[:users].access_allowed?(packet, packet['user.id'])
|
56
62
|
end
|
57
63
|
else
|
58
64
|
false
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'orange/middleware/base'
|
2
|
+
|
3
|
+
module Orange::Middleware
|
4
|
+
# The FlexRouter middleware takes a resource that can route paths and
|
5
|
+
# then intercepts routes for that resource. By default,
|
6
|
+
# it uses the Orange::SitemapResource.
|
7
|
+
#
|
8
|
+
# The resource is automatically loaded into the core as
|
9
|
+
# :sitemap. The resource must respond to "route?(path)"
|
10
|
+
# and "route(packet)".
|
11
|
+
#
|
12
|
+
# Pass a different routing resource using the :resource arg
|
13
|
+
class FourOhFour < Base
|
14
|
+
def init(opts = {})
|
15
|
+
@resource = opts[:resource] || Orange::NotFound
|
16
|
+
orange.load @resource.new, :not_found
|
17
|
+
end
|
18
|
+
|
19
|
+
# Sets the sitemap resource as the router if the resource can accept
|
20
|
+
# the path.
|
21
|
+
def packet_call(packet)
|
22
|
+
packet['route.router'] = orange[:not_found] unless packet['route.router']
|
23
|
+
pass packet
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
File without changes
|
@@ -40,7 +40,7 @@ module Orange::Middleware
|
|
40
40
|
@core = core
|
41
41
|
@libs = options[:libs] || [Orange::Core]
|
42
42
|
|
43
|
-
@urls = options[:urls] || ["/favicon.ico", "/assets/public"]
|
43
|
+
@urls = options[:urls] || ["/favicon.ico", "/assets/public", "/assets/uploaded"]
|
44
44
|
@root = options[:root] || File.join(orange.app_dir, 'assets')
|
45
45
|
@lib_urls = core.statics
|
46
46
|
@file_server = Orange::Middleware::StaticFile.new(@root)
|
@@ -56,7 +56,7 @@ module Orange::Middleware
|
|
56
56
|
packet['route.path'] = path.split(lib_url, 2).last
|
57
57
|
@file_server.call(packet.env)
|
58
58
|
elsif can_serve
|
59
|
-
packet['route.path'] = path
|
59
|
+
packet['route.path'] = path.gsub(/^\/assets/, '')
|
60
60
|
@file_server.call(packet.env)
|
61
61
|
else
|
62
62
|
pass packet
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
module Orange
|
3
|
+
class AssetResource < Orange::ModelResource
|
4
|
+
use Orange::Asset
|
5
|
+
call_me :assets
|
6
|
+
def afterLoad
|
7
|
+
orange[:admin, true].add_link("Content", :resource => @my_orange_name, :text => 'Assets')
|
8
|
+
orange.register(:stack_loaded) do
|
9
|
+
orange[:radius].context.define_tag "asset" do |tag|
|
10
|
+
if tag.attr['id']
|
11
|
+
(m = model_class.first(:id => tag.attr['id'])) ? m.to_asset_tag : 'Invalid Asset'
|
12
|
+
else
|
13
|
+
''
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def new(packet, *opts)
|
20
|
+
if packet.request.post?
|
21
|
+
params = packet.request.params[@my_orange_name.to_s]
|
22
|
+
if(file = params['file'][:tempfile])
|
23
|
+
file_path = orange.app_dir('assets','uploaded', params['file'][:filename]) if params['file'][:filename]
|
24
|
+
# Check for secondary file (useful for videos/images with thumbnails)
|
25
|
+
if(params['file2'] && secondary = params['file2'][:tempfile])
|
26
|
+
secondary_path = orange.app_dir('assets','uploaded', params['file2'][:filename])
|
27
|
+
else
|
28
|
+
secondary_path = nil
|
29
|
+
end
|
30
|
+
# Move the files
|
31
|
+
FileUtils.cp(file.path, file_path)
|
32
|
+
FileUtils.cp(secondary.path, secondary_path) if secondary_path
|
33
|
+
|
34
|
+
params['path'] = params['file'][:filename] if file_path
|
35
|
+
params['secondary_path'] = params['file2'][:filename] if secondary_path
|
36
|
+
params['mime_type'] = params['file'][:type] if file_path
|
37
|
+
params['secondary_mime_type'] = params['file2'][:type] if secondary_path
|
38
|
+
params.delete('file')
|
39
|
+
params.delete('file2')
|
40
|
+
|
41
|
+
model_class.new(params).save
|
42
|
+
end
|
43
|
+
end
|
44
|
+
packet.reroute(@my_orange_name, :orange)
|
45
|
+
end
|
46
|
+
|
47
|
+
def delete(packet, *opts)
|
48
|
+
if packet.request.delete?
|
49
|
+
m = model_class.get(packet['route.resource_id'])
|
50
|
+
begin
|
51
|
+
FileUtils.rm(orange.app_dir('assets','uploaded', m.path)) if m.path
|
52
|
+
FileUtils.rm(orange.app_dir('assets','uploaded', m.secondary_path)) if m.secondary_path
|
53
|
+
rescue
|
54
|
+
# Problem deleting file
|
55
|
+
end
|
56
|
+
m.destroy if m
|
57
|
+
end
|
58
|
+
packet.reroute(@my_orange_name, :orange)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -8,8 +8,9 @@ module Orange
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def route_to(packet, resource, *args)
|
11
|
+
opts = args.extract_options!
|
11
12
|
packet = DefaultHash.new unless packet
|
12
|
-
context = packet['route.context', nil]
|
13
|
+
context = opts[:context] || packet['route.context', nil]
|
13
14
|
site = packet['route.faked_site'] ? packet['route.site_url', nil] : nil
|
14
15
|
args.unshift(resource)
|
15
16
|
args.unshift(context)
|
@@ -16,8 +16,82 @@ module Orange
|
|
16
16
|
content = packet[:content, false]
|
17
17
|
unless content.blank?
|
18
18
|
parser = ::Radius::Parser.new(context, :tag_prefix => 'o')
|
19
|
-
packet[:content] = parser.parse(content)
|
19
|
+
packet[:content] = parser.parse(content, packet)
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
23
|
-
end
|
23
|
+
end
|
24
|
+
|
25
|
+
module Radius
|
26
|
+
#
|
27
|
+
# The Radius parser. Initialize a parser with a Context object that
|
28
|
+
# defines how tags should be expanded. See the QUICKSTART[link:files/QUICKSTART.html]
|
29
|
+
# for a detailed explaination of its usage.
|
30
|
+
#
|
31
|
+
class Parser
|
32
|
+
def parse(string, packet = false)
|
33
|
+
@stack = [ParseContainerTag.new { |t| t.contents.to_s }]
|
34
|
+
tokenize(string)
|
35
|
+
stack_up(packet)
|
36
|
+
@stack.last.to_s
|
37
|
+
end
|
38
|
+
|
39
|
+
protected
|
40
|
+
|
41
|
+
def stack_up(packet = false)
|
42
|
+
@tokens.each do |t|
|
43
|
+
if t.is_a? String
|
44
|
+
@stack.last.contents << t
|
45
|
+
next
|
46
|
+
end
|
47
|
+
case t[:flavor]
|
48
|
+
when :open
|
49
|
+
@stack.push(ParseContainerTag.new(t[:name], t[:attrs]))
|
50
|
+
when :self
|
51
|
+
@stack.last.contents << ParseTag.new {@context.render_tag(t[:name], t[:attrs], packet)}
|
52
|
+
when :close
|
53
|
+
popped = @stack.pop
|
54
|
+
raise WrongEndTagError.new(popped.name, t[:name], @stack) if popped.name != t[:name]
|
55
|
+
popped.on_parse { |b| @context.render_tag(popped.name, popped.attributes, packet) { b.contents.to_s } }
|
56
|
+
@stack.last.contents << popped
|
57
|
+
when :tasteless
|
58
|
+
raise TastelessTagError.new(t, @stack)
|
59
|
+
else
|
60
|
+
raise UndefinedFlavorError.new(t, @stack)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
raise MissingEndTagError.new(@stack.last.name, @stack) if @stack.length != 1
|
64
|
+
end
|
65
|
+
end
|
66
|
+
class Context
|
67
|
+
|
68
|
+
# Returns the value of a rendered tag. Used internally by Parser#parse.
|
69
|
+
def render_tag(name, attributes = {}, packet = false, &block)
|
70
|
+
if name =~ /^(.+?):(.+)$/
|
71
|
+
render_tag($1) { render_tag($2, attributes, packet, &block) }
|
72
|
+
else
|
73
|
+
tag_definition_block = @definitions[qualified_tag_name(name.to_s)]
|
74
|
+
if tag_definition_block
|
75
|
+
stack(name, attributes, packet, block) do |tag|
|
76
|
+
tag_definition_block.call(tag).to_s
|
77
|
+
end
|
78
|
+
else
|
79
|
+
tag_missing(name, attributes, &block)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
# A convienence method for managing the various parts of the
|
84
|
+
# tag binding stack.
|
85
|
+
def stack(name, attributes, packet, block)
|
86
|
+
previous = @tag_binding_stack.last
|
87
|
+
previous_locals = previous.nil? ? @globals : previous.locals
|
88
|
+
locals = DelegatingOpenStruct.new(previous_locals)
|
89
|
+
locals.packet = packet
|
90
|
+
binding = TagBinding.new(self, locals, name, attributes, block)
|
91
|
+
@tag_binding_stack.push(binding)
|
92
|
+
result = yield(binding)
|
93
|
+
@tag_binding_stack.pop
|
94
|
+
result
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -130,15 +130,15 @@ module Orange
|
|
130
130
|
packet.reroute(@my_orange_name, :orange)
|
131
131
|
end
|
132
132
|
|
133
|
-
def top_nav
|
134
|
-
|
135
|
-
end
|
136
|
-
|
137
133
|
def home(packet)
|
138
134
|
site_id = packet['site'].id
|
139
135
|
model_class.home_for_site(site_id) || model_class.create_home_for_site(site_id)
|
140
136
|
end
|
141
137
|
|
138
|
+
def two_level(packet)
|
139
|
+
do_view(packet, :two_level, :model => home(packet))
|
140
|
+
end
|
141
|
+
|
142
142
|
def routes_for(packet)
|
143
143
|
keys = {}
|
144
144
|
keys[:resource] = packet['route.resource'] unless packet['route.resource'].blank?
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Orange
|
2
|
+
class Slices < Orange::Resource
|
3
|
+
call_me :slices
|
4
|
+
def afterLoad
|
5
|
+
orange.register(:stack_loaded){
|
6
|
+
orange[:radius].context.define_tag "slice" do |tag|
|
7
|
+
content = ''
|
8
|
+
resource = (tag.attr['resource'] || :slices).to_sym
|
9
|
+
id = tag.attr['id'] || nil
|
10
|
+
mode = (tag.attr['mode'] || tag.attr['chunk'] || (id ? :show : :index )).to_sym
|
11
|
+
if orange.loaded?(resource)
|
12
|
+
if orange[resource].respond_to?(mode) || resource == :slices
|
13
|
+
content << (id ? orange[resource].__send__(mode, tag.locals.packet, :id => id) : orange[resource].__send__(mode, tag.locals.packet))
|
14
|
+
else
|
15
|
+
content << "resource #{resource} doesn't respond to #{mode}"
|
16
|
+
end
|
17
|
+
else
|
18
|
+
content << "resource #{resource} not loaded"
|
19
|
+
end
|
20
|
+
content
|
21
|
+
end
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
def method_missing(mode, *args)
|
27
|
+
packet = args.first if args.first.kind_of? Orange::Packet
|
28
|
+
opts = args.extract_options!
|
29
|
+
opts[:resource_name] = 'slices'
|
30
|
+
orange[:parser].haml("#{mode.to_s}.haml", packet, opts)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Orange
|
2
|
+
class UserResource < Orange::ModelResource
|
3
|
+
use Orange::User
|
4
|
+
call_me :users
|
5
|
+
def afterLoad
|
6
|
+
orange[:admin, true].add_link("Settings", :resource => @my_orange_name, :text => 'Users')
|
7
|
+
end
|
8
|
+
|
9
|
+
def access_allowed?(packet, user)
|
10
|
+
u = model_class.first(:open_id => user)
|
11
|
+
return false unless u
|
12
|
+
u.allowed?(packet)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/orange/stack.rb
CHANGED
@@ -132,7 +132,7 @@ module Orange
|
|
132
132
|
# A shortcut to enable Rack::OpenID and Orange::Middleware::AccessControl
|
133
133
|
#
|
134
134
|
# Args will be passed on to Orange::Middleware::AccessControl
|
135
|
-
# @todo Make it so this is not dependent on the openid_dm_store gem
|
135
|
+
# @todo Make it so this is not dependent on the openid_dm_store gem (outdated)
|
136
136
|
def openid_access_control(*args)
|
137
137
|
opts = args.extract_options!
|
138
138
|
require 'rack/openid'
|
data/spec/orange/core_spec.rb
CHANGED
@@ -122,6 +122,13 @@ describe Orange::Core do
|
|
122
122
|
c.app_dir.should == "/non/existent/dir"
|
123
123
|
end
|
124
124
|
|
125
|
+
it "should return assigned app_dir with extra path if args passed" do
|
126
|
+
c= Orange::Core.new
|
127
|
+
c.options[:app_dir] = "/non/existent/dir"
|
128
|
+
c.app_dir('foo', 'bar').should_not == c.app_dir
|
129
|
+
c.app_dir('foo', 'bar').should == "/non/existent/dir/foo/bar"
|
130
|
+
end
|
131
|
+
|
125
132
|
it "should allow options" do
|
126
133
|
c= Orange::Core.new(:opt_1 => true){ opt_2 true }
|
127
134
|
c.options[:opt_1].should == true
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: orange
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Haslem
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-02-
|
12
|
+
date: 2010-02-17 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -53,14 +53,14 @@ dependencies:
|
|
53
53
|
version: 2.2.13
|
54
54
|
version:
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: rack-abstract-format
|
57
57
|
type: :runtime
|
58
58
|
version_requirement:
|
59
59
|
version_requirements: !ruby/object:Gem::Requirement
|
60
60
|
requirements:
|
61
61
|
- - ">="
|
62
62
|
- !ruby/object:Gem::Version
|
63
|
-
version: 0.9.
|
63
|
+
version: 0.9.9
|
64
64
|
version:
|
65
65
|
- !ruby/object:Gem::Dependency
|
66
66
|
name: rack-openid
|
@@ -73,14 +73,14 @@ dependencies:
|
|
73
73
|
version: 0.2.2
|
74
74
|
version:
|
75
75
|
- !ruby/object:Gem::Dependency
|
76
|
-
name:
|
76
|
+
name: openid_dm_store
|
77
77
|
type: :runtime
|
78
78
|
version_requirement:
|
79
79
|
version_requirements: !ruby/object:Gem::Requirement
|
80
80
|
requirements:
|
81
81
|
- - ">="
|
82
82
|
- !ruby/object:Gem::Version
|
83
|
-
version: 0.1.
|
83
|
+
version: 0.1.3
|
84
84
|
version:
|
85
85
|
- !ruby/object:Gem::Dependency
|
86
86
|
name: dm-is-awesome_set
|
@@ -134,18 +134,21 @@ files:
|
|
134
134
|
- lib/orange.rb
|
135
135
|
- lib/orange/application.rb
|
136
136
|
- lib/orange/carton.rb
|
137
|
+
- lib/orange/cartons/asset_carton.rb
|
137
138
|
- lib/orange/cartons/page_carton.rb
|
138
139
|
- lib/orange/cartons/page_version_carton.rb
|
139
140
|
- lib/orange/cartons/site_carton.rb
|
141
|
+
- lib/orange/cartons/user_carton.rb
|
140
142
|
- lib/orange/core.rb
|
141
143
|
- lib/orange/magick.rb
|
142
144
|
- lib/orange/middleware/access_control.rb
|
143
145
|
- lib/orange/middleware/base.rb
|
144
146
|
- lib/orange/middleware/database.rb
|
145
147
|
- lib/orange/middleware/flex_router.rb
|
148
|
+
- lib/orange/middleware/four_oh_four.rb
|
146
149
|
- lib/orange/middleware/globals.rb
|
147
150
|
- lib/orange/middleware/loader.rb
|
148
|
-
- lib/orange/middleware/
|
151
|
+
- lib/orange/middleware/radius_parser.rb
|
149
152
|
- lib/orange/middleware/rerouter.rb
|
150
153
|
- lib/orange/middleware/restful_router.rb
|
151
154
|
- lib/orange/middleware/route_context.rb
|
@@ -158,8 +161,10 @@ files:
|
|
158
161
|
- lib/orange/packet.rb
|
159
162
|
- lib/orange/resource.rb
|
160
163
|
- lib/orange/resources/admin_resource.rb
|
164
|
+
- lib/orange/resources/asset_resource.rb
|
161
165
|
- lib/orange/resources/mapper.rb
|
162
166
|
- lib/orange/resources/model_resource.rb
|
167
|
+
- lib/orange/resources/not_found.rb
|
163
168
|
- lib/orange/resources/page_parts.rb
|
164
169
|
- lib/orange/resources/page_resource.rb
|
165
170
|
- lib/orange/resources/parser.rb
|
@@ -167,6 +172,8 @@ files:
|
|
167
172
|
- lib/orange/resources/routable_resource.rb
|
168
173
|
- lib/orange/resources/singleton_model_resource.rb
|
169
174
|
- lib/orange/resources/sitemap_resource.rb
|
175
|
+
- lib/orange/resources/slices.rb
|
176
|
+
- lib/orange/resources/user_resource.rb
|
170
177
|
- lib/orange/stack.rb
|
171
178
|
- README.markdown
|
172
179
|
has_rdoc: true
|