dope 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile ADDED
@@ -0,0 +1,63 @@
1
+
2
+ require 'rubygems'
3
+ require 'rake/gempackagetask'
4
+
5
+ $LOAD_PATH.unshift('lib')
6
+ require 'dope'
7
+
8
+ spec = Gem::Specification.new do |s|
9
+
10
+ s.name = 'dope'
11
+ s.rubyforge_project = 'dope'
12
+ s.version = Dope::VERSION
13
+ s.author = Dope::AUTHORS.first
14
+ s.homepage = Dope::WEBSITE
15
+ s.summary = "A way to export Welo resources on Derailleur"
16
+ s.email = "crapooze@gmail.com"
17
+ s.platform = Gem::Platform::RUBY
18
+
19
+ s.files = [
20
+ 'Rakefile',
21
+ 'TODO',
22
+ 'lib/dope.rb',
23
+ 'lib/dope/core/application.rb',
24
+ 'lib/dope/core/context.rb',
25
+ 'lib/dope/core/handler.rb',
26
+ 'lib/dope/core/resource.rb',
27
+ 'lib/dope/core/view.rb',
28
+ ]
29
+
30
+ s.require_path = 'lib'
31
+ s.bindir = 'bin'
32
+ s.executables = []
33
+ s.has_rdoc = true
34
+ end
35
+
36
+ Rake::GemPackageTask.new(spec) do |pkg|
37
+ pkg.need_tar = true
38
+ end
39
+
40
+ task :gem => ["pkg/#{spec.name}-#{spec.version}.gem"] do
41
+ puts "generated #{spec.version}"
42
+ end
43
+
44
+
45
+ desc "run an example"
46
+ task :example, :ex, :server, :port do |t, params|
47
+ path = "./example/#{params[:ex]}.rb"
48
+ servername = params[:server] || 'thin'
49
+ port = params[:port] || '3000'
50
+ if File.file? path
51
+ require path
52
+ require 'rack'
53
+ app = Rack::Builder.new {
54
+ run ExampleApplication
55
+ }
56
+ server = Rack::Handler.get(servername)
57
+ server.run(app, :Port => port.to_i)
58
+ else
59
+ puts "no such example: #{path}
60
+ use ls example to see the possibilities"
61
+
62
+ end
63
+ end
data/TODO ADDED
@@ -0,0 +1,16 @@
1
+ * specs
2
+ * static file handler
3
+ - create a class generator instead of current one and only one static approach
4
+ - better mime-types handling
5
+ * export resource models
6
+ - relations: get the data from the relationship:
7
+ -> currently values to iterate on are passed as parameters
8
+ -> we could get them from the relationship
9
+ -> ideally, the model could also be taken internally
10
+ - epithet
11
+ -> handler for epithet, current model handler uses match?, we will need to use
12
+ epithet_resource_match_params?
13
+ * use perspectives in the handlers
14
+ - possibility to export one resource with a limited number of perspectives?
15
+ * (unlikely) case which may break
16
+ - multiple nesting of similar resources => risk of parameter namespacing issue?
@@ -0,0 +1,185 @@
1
+
2
+ require 'derailleur'
3
+ require 'dope/core/handler'
4
+ autoload :Find, 'find'
5
+
6
+ module Dope
7
+ module Application
8
+ include Derailleur::Application
9
+
10
+ def get_resource_at_path(resource, path)
11
+ puts "R: #{path}"
12
+ get(path, ResourceHandler.new(resource))
13
+ end
14
+
15
+ def get_resource(resource, root='', ident=:default)
16
+ path = File.join(root, resource.path(ident))
17
+ get_resource_at_path(resource, path)
18
+ end
19
+
20
+ def unget_resource(resource, root='', ident=:default)
21
+ path = File.join(root, resource.path(ident))
22
+ unget(path)
23
+ end
24
+
25
+ def get_linked_resource(link, root='')
26
+ branch = link.to_s.sub(/^\.\//,'')
27
+ path = File.join(root, branch)
28
+ get_resource_at_path(link.to, path)
29
+ end
30
+
31
+ def unget_linked_resource(link, root='')
32
+ branch = link.to_s.sub(/^\.\//,'')
33
+ path = File.join(root, branch)
34
+ unget(path)
35
+ end
36
+
37
+ def get_resource_relation(resource, relname, root='', ident=:default)
38
+ rel = resource.relationship(relname)
39
+ raise ArgumentError, "no relationship: #{relname} for #{resource}" unless rel
40
+ link = resource.link_for_rel(rel)
41
+ path = File.join(root, resource.path(ident))
42
+ case link
43
+ when Welo::Link
44
+ get_linked_resource(link, path)
45
+ when Welo::LinksEnumerator
46
+ link.each do |l|
47
+ get_linked_resource(l, path)
48
+ end
49
+ else
50
+ raise RuntimeError, "unknown kind of link: #{link}"
51
+ end
52
+ end
53
+
54
+ def unget_resource_relation(resource, relname, root='', ident=:default)
55
+ rel = resource.relationship(relname)
56
+ raise ArgumentError, "no relationship: #{relname} for #{resource}" unless rel
57
+ link = resource.link_for_rel(rel)
58
+ path = File.join(root, resource.path(ident))
59
+ case link
60
+ when Welo::Link
61
+ unget_linked_resource(link, path)
62
+ when Welo::LinksEnumerator
63
+ link.each do |l|
64
+ unget_linked_resource(l, path)
65
+ end
66
+ else
67
+ raise RuntimeError, "unknown kind of link: #{link}"
68
+ end
69
+ end
70
+
71
+ def get_resource_model_at_path(model, ident, resources, path)
72
+ puts "M: #{path}"
73
+ get(path, ResourceModelHandler.new([model, ident, resources]))
74
+ end
75
+
76
+ def get_resource_model(model, resources, root='', ident=:default)
77
+ path = File.join(root, model.path_model(ident, "#{model.base_path}."))
78
+ get_resource_model_at_path(model, ident, resources, path)
79
+ end
80
+
81
+ def unget_resource_model(model, root='', ident=:default)
82
+ path = File.join(root, model.path_model(ident, "#{model.base_path}."))
83
+ unget(path)
84
+ end
85
+
86
+ def get_resource_nesting_model(resource, relname, model, resources, root='', ident=:default)
87
+ nesting = resource.nesting(relname)
88
+ raise ArgumentError, "no nesting: #{relname} for #{resource}" unless nesting
89
+ model_ident = nesting.identifier_sym
90
+ path = File.join(root, resource.path(ident))
91
+ get_resource_model(model, resources, path, model_ident)
92
+ end
93
+
94
+ def unget_resource_nesting_model(resource, relname, model, root='', ident=:default)
95
+ nesting = resource.nesting(relname)
96
+ raise ArgumentError, "no nesting: #{relname} for #{resource}" unless nesting
97
+ model_ident = nesting.identifier_sym
98
+ path = File.join(root, resource.path(ident))
99
+ unget_resource_model(model, path, model_ident)
100
+ end
101
+
102
+ def get_resource_epitheting_model(resource, label, model, resources, root='', ident=:default)
103
+ epithet = resource.epithet(label)
104
+ raise ArgumentError, "no epithet: #{label} for #{resource}" unless epithet
105
+ branch = resource.epithets(label, "#{model.base_path}.")
106
+ path = File.join(root, resource.path(ident), label.to_s, branch)
107
+ get_resource_epitheting_model_at_path(resource, model, label, resources, path)
108
+ end
109
+
110
+ def get_resource_epitheting_model_at_path(resource, model, label, resources, path)
111
+ puts "E: #{path}"
112
+ get(path, ResourceEpithetingModelHandler.new([model, label, resources, resource]))
113
+ end
114
+
115
+ # multi-level
116
+
117
+ def get_resource_relation_tree(resource, tree=[], root='', ident=:default)
118
+ path = if ident
119
+ File.join(root, resource.path(ident))
120
+ else
121
+ root
122
+ end
123
+ tree.each do |node|
124
+ relname, subtree = if node.is_a? Array
125
+ [node.first, node[1 .. -1]]
126
+ else
127
+ [node, []]
128
+ end
129
+ rel = resource.relationship(relname)
130
+ raise ArgumentError, "no relationship: #{relname} for #{resource}" unless rel
131
+ link = resource.link_for_rel(rel)
132
+ case link
133
+ when Welo::Link
134
+ get_linked_resource(link, path)
135
+ unless subtree.empty?
136
+ branch = link.to_s.sub(/^\.\//,'')
137
+ new_root = File.join(path, branch)
138
+ get_resource_relation_tree(link.to, subtree, new_root, nil)
139
+ end
140
+ when Welo::LinksEnumerator
141
+ link.each do |l|
142
+ get_linked_resource(l, path)
143
+ unless subtree.empty?
144
+ branch = link.to_s.sub(/^\.\//,'')
145
+ new_root = File.join(path, branch)
146
+ get_resource_relation_tree(link.to, subtree, new_root, nil)
147
+ end
148
+ end
149
+ else
150
+ raise RuntimeError, "unknown kind of link: #{link}"
151
+ end
152
+ end
153
+ end
154
+
155
+ def get_resource_relation_chain(resource, relnames=[], root='', ident=:default)
156
+ tree = []
157
+ last = tree
158
+ relnames.each do |sym|
159
+ ary = [sym]
160
+ last << ary
161
+ last = ary
162
+ end
163
+ get_resource_relation_tree(resource, tree, root, ident)
164
+ end
165
+
166
+
167
+ # file-system assets' handling
168
+
169
+ def static_dir(dir)
170
+ Find.find(dir) do |path|
171
+ if File.file?(path)
172
+ static_file path, dir
173
+ end
174
+ end
175
+ end
176
+
177
+ def static_file(path, dir='')
178
+ route = path.sub(dir,'')
179
+ puts "F: #{route}"
180
+ StaticFileHandler.register(route, path)
181
+ get(route.sub(/\.\w+$/,''), StaticFileHandler)
182
+ rescue Derailleur::RouteObjectAlreadyPresent
183
+ end
184
+ end
185
+ end
@@ -0,0 +1,60 @@
1
+
2
+ autoload :Rack, 'rack/utils'
3
+ require 'derailleur/base/context'
4
+ require 'mime/types'
5
+
6
+ module Dope
7
+ class ResourceContext < Derailleur::Context
8
+ attr_reader :resource
9
+ def initialize(env, ctx, resource, &blk)
10
+ super(env, ctx, &blk)
11
+ @resource = resource
12
+ end
13
+
14
+ def perspective
15
+ (Rack::Utils.parse_query(env['QUERY_STRING'])['perspective'] || 'default').to_sym
16
+ end
17
+
18
+ def default_ext
19
+ '.html'
20
+ end
21
+
22
+ def default_content_type
23
+ 'text/plain'
24
+ end
25
+
26
+ def ext
27
+ ret = extname
28
+ return default_ext if ret.empty?
29
+ ret
30
+ end
31
+
32
+ #XXX bitchy: all the if ext == '.html' may go to the code in the view
33
+ def content
34
+ e = ext
35
+ if e == '.html'
36
+ resource.view.render(self)
37
+ else
38
+ resource.to_ext(e, self)
39
+ end
40
+ end
41
+
42
+ def mime_types
43
+ MIME::Types.of(ext)
44
+ end
45
+
46
+ def content_type
47
+ m = mime_types
48
+ if m
49
+ m.first.to_s
50
+ else
51
+ default_content_type
52
+ end
53
+ end
54
+
55
+ def headers
56
+ {'Content-Type' => content_type}
57
+ end
58
+
59
+ end
60
+ end
@@ -0,0 +1,105 @@
1
+
2
+ require 'dope/core/context'
3
+ require 'derailleur/core/handler'
4
+ require 'mime/types'
5
+
6
+ module Dope
7
+ class StaticFileHandler < Derailleur::RackHandler
8
+ class NoSuchStaticFile < Derailleur::NoSuchRoute
9
+ end
10
+
11
+ @registrations = {}
12
+
13
+ class << self
14
+ attr_reader :registrations
15
+
16
+ def register(route, path)
17
+ registrations[route] = path
18
+ end
19
+ end
20
+
21
+ def path
22
+ self.class.registrations[env['PATH_INFO']]
23
+ end
24
+
25
+ def extname
26
+ File.extname(env['PATH_INFO'])
27
+ end
28
+
29
+ def mime_types
30
+ MIME::Types.of(path)
31
+ end
32
+
33
+ def content_type
34
+ m = mime_types
35
+ m.first.to_s if m
36
+ end
37
+
38
+ def to_rack_output
39
+ raise NoSuchStaticFile, "no such file (#{path}) for #{env['PATH_INFO']}" unless path and File.file?(path)
40
+ [200, {'Content-Type' => content_type}, File.read(path)]
41
+ end
42
+ end
43
+
44
+ class ResourceHandler < Derailleur::Handler
45
+ alias :resource :object
46
+
47
+ def to_rack_output
48
+ context = ResourceContext.new(env, ctx, resource)
49
+ context.result
50
+ end
51
+ end
52
+
53
+ class ResourceNotFound < Derailleur::NoSuchRoute
54
+ end
55
+
56
+ class ResourceModelHandler < Derailleur::Handler
57
+ def model
58
+ object[0]
59
+ end
60
+
61
+ def resources
62
+ object[2]
63
+ end
64
+
65
+ def prefix
66
+ ":#{model.base_path}."
67
+ end
68
+
69
+ def to_rack_output
70
+ resource = find_resource
71
+ raise ResourceNotFound unless resource
72
+ ResourceHandler.new(resource, env, ctx).to_rack_output
73
+ end
74
+ end
75
+
76
+ class ResourceNestingModelHandler < ResourceModelHandler
77
+ def ident
78
+ object[1]
79
+ end
80
+
81
+ def find_resource
82
+ params = ctx['derailleur.params'].dup
83
+ params.delete(:splat)
84
+ resources.find{|r| r.match_params?(params, ident, prefix)}
85
+ end
86
+ end
87
+
88
+ class ResourceEpithetingModelHandler < ResourceModelHandler
89
+ def label
90
+ object[1]
91
+ end
92
+
93
+ def resource
94
+ object[3]
95
+ end
96
+
97
+ def find_resource
98
+ params = ctx['derailleur.params'].dup
99
+ params.delete(:splat)
100
+ found = resources.find do |r|
101
+ resource.epithet_resource_match_params?(r, params, label, prefix)
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,30 @@
1
+
2
+ require 'welo'
3
+
4
+ module Dope
5
+ autoload :View, 'dope/core/view'
6
+ module Resource
7
+ include Welo::Resource
8
+ def self.included(mod)
9
+ mod.extend Welo::Resource::ClassMethods
10
+ mod.extend ClassMethods
11
+ end
12
+
13
+ module ClassMethods
14
+ def view(val=nil)
15
+ if val
16
+ @view = val
17
+ end
18
+ @view
19
+ end
20
+ end
21
+
22
+ def view_klass
23
+ self.class.view
24
+ end
25
+
26
+ def view
27
+ view_klass.new(self)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,13 @@
1
+
2
+ module Dope
3
+ class View
4
+ attr_reader :resource
5
+ def initialize(resource)
6
+ @resource = resource
7
+ end
8
+
9
+ def render(ctx)
10
+ "hello from #{self} for #{resource} in #{ctx}"
11
+ end
12
+ end
13
+ end
data/lib/dope.rb ADDED
@@ -0,0 +1,10 @@
1
+
2
+ module Dope
3
+ VERSION = "0.0.2"
4
+ AUTHORS = ["crapooze"]
5
+ WEBSITE = "https://github.com/crapooze/dope"
6
+ LICENCE = "MIT"
7
+ autoload :Application, 'dope/core/application'
8
+ autoload :Resource, 'dope/core/resource'
9
+ autoload :View, 'dope/core/view'
10
+ end
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dope
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 2
9
+ version: 0.0.2
10
+ platform: ruby
11
+ authors:
12
+ - crapooze
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-02-14 00:00:00 +01:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description:
22
+ email: crapooze@gmail.com
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files: []
28
+
29
+ files:
30
+ - Rakefile
31
+ - TODO
32
+ - lib/dope.rb
33
+ - lib/dope/core/application.rb
34
+ - lib/dope/core/context.rb
35
+ - lib/dope/core/handler.rb
36
+ - lib/dope/core/resource.rb
37
+ - lib/dope/core/view.rb
38
+ has_rdoc: true
39
+ homepage: https://github.com/crapooze/dope
40
+ licenses: []
41
+
42
+ post_install_message:
43
+ rdoc_options: []
44
+
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ none: false
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ segments:
53
+ - 0
54
+ version: "0"
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ segments:
61
+ - 0
62
+ version: "0"
63
+ requirements: []
64
+
65
+ rubyforge_project: dope
66
+ rubygems_version: 1.3.7
67
+ signing_key:
68
+ specification_version: 3
69
+ summary: A way to export Welo resources on Derailleur
70
+ test_files: []
71
+