wire-framework 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.
- checksums.yaml +7 -0
- data/LICENSE +340 -0
- data/README.md +6 -0
- data/lib/app.rb +27 -0
- data/lib/app/db.rb +174 -0
- data/lib/app/file.rb +81 -0
- data/lib/app/history.rb +59 -0
- data/lib/app/history/svn.rb +34 -0
- data/lib/app/login.rb +14 -0
- data/lib/app/render.rb +121 -0
- data/lib/app/render/document.rb +51 -0
- data/lib/app/render/editor.rb +55 -0
- data/lib/app/render/instant.rb +65 -0
- data/lib/app/render/page.rb +91 -0
- data/lib/app/render/partial.rb +110 -0
- data/lib/app/render/style.rb +52 -0
- data/lib/app/repo.rb +148 -0
- data/lib/app/repo/svn.rb +177 -0
- data/lib/closet.rb +99 -0
- data/lib/closet/auth.rb +55 -0
- data/lib/closet/context.rb +103 -0
- data/lib/closet/renderer.rb +46 -0
- data/lib/closet/resource.rb +18 -0
- data/lib/wire.rb +28 -0
- metadata +208 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
require_relative '../render'
|
|
2
|
+
|
|
3
|
+
module Render
|
|
4
|
+
# Page builds the a page that is presented directly to a user
|
|
5
|
+
# @author Bryan T. Meyers
|
|
6
|
+
module Page
|
|
7
|
+
include Render
|
|
8
|
+
extend self
|
|
9
|
+
|
|
10
|
+
# Render a full template, handling the gathering of additional Sources
|
|
11
|
+
# @param [Array] actions the allowed actions for this URI
|
|
12
|
+
# @param [Hash] context the context for this request
|
|
13
|
+
# @param [Tilt::Template] template a pre-loaded Tilt template to render
|
|
14
|
+
# @param [String] content the content to render into the page
|
|
15
|
+
# @return [Response] a Rack Response triplet, or status code
|
|
16
|
+
def render_template(actions, context, template, content)
|
|
17
|
+
if template[:path]
|
|
18
|
+
hash = { actions: actions, context: context, content: content }
|
|
19
|
+
template[:sources].each do |k, s|
|
|
20
|
+
uri = "http://#{context.app[:remote_host]}/#{s[:uri]}"
|
|
21
|
+
case s[:key]
|
|
22
|
+
when :user
|
|
23
|
+
uri += "/#{context.user}"
|
|
24
|
+
when :resource
|
|
25
|
+
uri += "/#{context.uri[2]}"
|
|
26
|
+
end
|
|
27
|
+
begin
|
|
28
|
+
temp = RestClient.get uri
|
|
29
|
+
rescue RestClient::ResourceNotFound
|
|
30
|
+
temp = nil
|
|
31
|
+
end
|
|
32
|
+
hash[k] = temp
|
|
33
|
+
end
|
|
34
|
+
message = template[:path].render(self, hash)
|
|
35
|
+
if template[:use_layout]
|
|
36
|
+
message = render_template(actions, context, $apps[:global][:template], message)
|
|
37
|
+
end
|
|
38
|
+
else
|
|
39
|
+
message = 'Invalid Template'
|
|
40
|
+
end
|
|
41
|
+
message
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Render a page to its final form
|
|
45
|
+
# @param [Array] actions the allowed actions for this URI
|
|
46
|
+
# @param [Hash] context the context for this request
|
|
47
|
+
# @param [Symbol] specific the kind of read to perform
|
|
48
|
+
# @return [Response] a Rack Response triplet, or status code
|
|
49
|
+
def do_read(actions, context, specific)
|
|
50
|
+
template = context.app[:template]
|
|
51
|
+
resource = context.uri[2]
|
|
52
|
+
message = 'Resource not specified'
|
|
53
|
+
headers = {}
|
|
54
|
+
if resource
|
|
55
|
+
begin
|
|
56
|
+
result = forward(specific, context)
|
|
57
|
+
if template
|
|
58
|
+
message = render_template(actions, context, template, result)
|
|
59
|
+
else
|
|
60
|
+
headers['Content-Type'] = result.headers[:content_type]
|
|
61
|
+
message = [200, headers, [result.to_str]]
|
|
62
|
+
end
|
|
63
|
+
rescue RestClient::ResourceNotFound
|
|
64
|
+
message = 404
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
message
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Proxy method used when routing
|
|
71
|
+
# @param [Array] actions the allowed actions for this URI
|
|
72
|
+
# @param [Hash] context the context for this request
|
|
73
|
+
# @return [Response] a Rack Response triplet, or status code
|
|
74
|
+
def self.invoke(actions, context)
|
|
75
|
+
case context.action
|
|
76
|
+
when :create
|
|
77
|
+
forward(:create, context)
|
|
78
|
+
when :read
|
|
79
|
+
if context.uri[3]
|
|
80
|
+
do_read(actions, context, :read)
|
|
81
|
+
else
|
|
82
|
+
do_read(actions, context, :readAll)
|
|
83
|
+
end
|
|
84
|
+
when :update
|
|
85
|
+
forward(:update, context)
|
|
86
|
+
else
|
|
87
|
+
405
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
require_relative '../render'
|
|
2
|
+
|
|
3
|
+
module Render
|
|
4
|
+
# Partials are URI mapped renderers which generate only a piece of a document
|
|
5
|
+
# @author Bryan T.Meyers
|
|
6
|
+
module Partial
|
|
7
|
+
extend Render
|
|
8
|
+
|
|
9
|
+
# DSL method to enable forwarding to remote
|
|
10
|
+
# @return [void]
|
|
11
|
+
def self.use_forward
|
|
12
|
+
$current_resource[:forward] = true
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# DSL method to pull in Source like objects
|
|
16
|
+
# @param [Symbol] name the key for this item
|
|
17
|
+
# @param [Hash] path the remote sub-URI for this item
|
|
18
|
+
# @return [void]
|
|
19
|
+
def self.extra(name, path)
|
|
20
|
+
unless $current_resource[:sources]
|
|
21
|
+
$current_resource[:sources] = {}
|
|
22
|
+
end
|
|
23
|
+
$current_resource[:sources][name] = path
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Read a listing and render to HTML
|
|
27
|
+
# @param [Array] actions the allowed actions for this URI
|
|
28
|
+
# @param [Hash] context the context for this request
|
|
29
|
+
# @return [Response] a Rack Response triplet, or status code
|
|
30
|
+
def self.do_read_all(actions, context)
|
|
31
|
+
resource = context.uri[2]
|
|
32
|
+
begin
|
|
33
|
+
mime = ''
|
|
34
|
+
body = ''
|
|
35
|
+
if context.resource[:forward]
|
|
36
|
+
response = forward(:readAll, context)
|
|
37
|
+
mime = response.headers[:content_type]
|
|
38
|
+
body = response.body
|
|
39
|
+
else
|
|
40
|
+
body = 401
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
template = context.resource[:multiple]
|
|
44
|
+
hash = { actions: actions, resource: resource, mime: mime, response: body }
|
|
45
|
+
if context.resource[:sources]
|
|
46
|
+
context.resource[:sources].each do |k, v|
|
|
47
|
+
hash[k] = RestClient.get("http://#{context.app[:remote_host]}/#{v}")
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
mime = 'text/html'
|
|
51
|
+
if template
|
|
52
|
+
[200, { 'Content-Type' => mime }, [template.render(self, hash)]]
|
|
53
|
+
else
|
|
54
|
+
[200, { 'Content-Type' => mime }, [body]]
|
|
55
|
+
end
|
|
56
|
+
rescue RestClient::ResourceNotFound
|
|
57
|
+
404
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Read a Partial and render it to HTML
|
|
62
|
+
# @param [Array] actions the allowed actions for this URI
|
|
63
|
+
# @param [Hash] context the context for this request
|
|
64
|
+
# @return [Response] a Rack Response triplet, or status code
|
|
65
|
+
def self.do_read(actions, context)
|
|
66
|
+
app = context.app[:uri]
|
|
67
|
+
resource = context.uri[2]
|
|
68
|
+
begin
|
|
69
|
+
response = forward(:read, context)
|
|
70
|
+
mime = response.headers[:content_type]
|
|
71
|
+
template = context.resource[:single]
|
|
72
|
+
id = context.uri[3...context.uri.length].join('/')
|
|
73
|
+
hash = { actions: actions, app: app, id: id, resource: resource, mime: mime, response: response.body }
|
|
74
|
+
if context.resource[:sources]
|
|
75
|
+
context.resource[:sources].each do |k, v|
|
|
76
|
+
hash[k] = RestClient.get("http://#{context.app[:remote_host]}/#{v}")
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
if template
|
|
80
|
+
[200, { 'Content-Type' => 'text/html' }, [template.render(self, hash)]]
|
|
81
|
+
else
|
|
82
|
+
[200, { 'Content-Type' => 'text/plain' }, [response.body]]
|
|
83
|
+
end
|
|
84
|
+
rescue RestClient::ResourceNotFound
|
|
85
|
+
404
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Proxy method used when routing
|
|
90
|
+
# @param [Array] actions the allowed actions for this URI
|
|
91
|
+
# @param [Hash] context the context for this request
|
|
92
|
+
# @return [Response] a Rack Response triplet, or status code
|
|
93
|
+
def self.invoke(actions, context)
|
|
94
|
+
case context.action
|
|
95
|
+
when :create
|
|
96
|
+
forward(:create, context)
|
|
97
|
+
when :read
|
|
98
|
+
if context.uri[3]
|
|
99
|
+
do_read(actions, context)
|
|
100
|
+
else
|
|
101
|
+
do_read_all(actions, context)
|
|
102
|
+
end
|
|
103
|
+
when :update
|
|
104
|
+
forward(:update, context)
|
|
105
|
+
else
|
|
106
|
+
403
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
require_relative '../render'
|
|
2
|
+
|
|
3
|
+
module Render
|
|
4
|
+
# Style uses Tilt to render and serve stylesheets
|
|
5
|
+
# @author Bryan T. Meyers
|
|
6
|
+
module Style
|
|
7
|
+
extend Render
|
|
8
|
+
|
|
9
|
+
# DSL method to create a style
|
|
10
|
+
# @param [String] resource the sub-URI for this style
|
|
11
|
+
# @param [Hash] path the file location of the stylesheet
|
|
12
|
+
# @return [void]
|
|
13
|
+
def self.style(resource, path)
|
|
14
|
+
unless $current_app[:styles]
|
|
15
|
+
$current_app[:styles] = {}
|
|
16
|
+
end
|
|
17
|
+
$current_app[:styles][resource] = path.nil? ? nil : Tilt.new(path, 1, { ugly: true }).render
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Render a stylesheet to CSS
|
|
21
|
+
# @param [Hash] context the context for this request
|
|
22
|
+
# @return [Response] a Rack Response triplet, or status code
|
|
23
|
+
def self.do_read_all(context)
|
|
24
|
+
begin
|
|
25
|
+
resource = context.uri[2]
|
|
26
|
+
template = context.app[:styles][resource]
|
|
27
|
+
headers = {}
|
|
28
|
+
if template
|
|
29
|
+
headers['Content-Type'] = 'text/css'
|
|
30
|
+
[200, headers, [template]]
|
|
31
|
+
else
|
|
32
|
+
500
|
|
33
|
+
end
|
|
34
|
+
rescue RestClient::ResourceNotFound
|
|
35
|
+
404
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Proxy method used when routing
|
|
40
|
+
# @param [Array] actions the allowed actions for this URI
|
|
41
|
+
# @param [Hash] context the context for this request
|
|
42
|
+
# @return [Response] a Rack Response triplet, or status code
|
|
43
|
+
def self.invoke(actions, context)
|
|
44
|
+
case context.action
|
|
45
|
+
when :read
|
|
46
|
+
do_read_all(context)
|
|
47
|
+
else
|
|
48
|
+
403
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
data/lib/app/repo.rb
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
require 'awesome_print'
|
|
2
|
+
require 'base64'
|
|
3
|
+
require_relative '../wire'
|
|
4
|
+
require_relative 'repo/svn'
|
|
5
|
+
|
|
6
|
+
# Repo is a Wire::App for accessing versioned content
|
|
7
|
+
# @author Bryan T. Meyers
|
|
8
|
+
module Repo
|
|
9
|
+
|
|
10
|
+
# Select the location of the repositories
|
|
11
|
+
# @param [Symbol] path location of the repositories
|
|
12
|
+
# @return [void]
|
|
13
|
+
def repos(path)
|
|
14
|
+
$current_app[:repos_path] = path
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Select the render template for file listings
|
|
18
|
+
# @param [Symbol] path location of the Tilt compatible template
|
|
19
|
+
# @return [void]
|
|
20
|
+
def listing(path)
|
|
21
|
+
$current_app[:template] = Tilt.new(path, 1, { ugly: true })
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Select the sub-directory for web-serveable content
|
|
25
|
+
# @param [Symbol] path the sub-directory path
|
|
26
|
+
# @return [void]
|
|
27
|
+
def web_folder(path)
|
|
28
|
+
$current_app[:web] = path
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Create a new Repo
|
|
32
|
+
# @param [Hash] context the context for this request
|
|
33
|
+
# @return [Response] status code
|
|
34
|
+
def do_create(context)
|
|
35
|
+
path = context.app[:repos_path]
|
|
36
|
+
resource = context.uri[2]
|
|
37
|
+
if path
|
|
38
|
+
if Dir.exist?("#{path}/#{resource}")
|
|
39
|
+
401
|
|
40
|
+
else
|
|
41
|
+
do_create_file(path, resource)
|
|
42
|
+
end
|
|
43
|
+
else
|
|
44
|
+
400
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Get the a root directory listing
|
|
49
|
+
# @param [Hash] context the context for this request
|
|
50
|
+
# @return [Response] the listing, or status code
|
|
51
|
+
def do_read_all(context)
|
|
52
|
+
resource = context.uri[2]
|
|
53
|
+
referrer = context.referer
|
|
54
|
+
repos = context.app[:repos_path]
|
|
55
|
+
web = context.app[:web]
|
|
56
|
+
mime = 'text/html'
|
|
57
|
+
list = do_read_listing(web, repos, resource)
|
|
58
|
+
if list == 404
|
|
59
|
+
return 404
|
|
60
|
+
end
|
|
61
|
+
template = context.app[:template]
|
|
62
|
+
list = template.render(self, list: list, resource: resource, id: '', referrer: referrer)
|
|
63
|
+
headers = {}
|
|
64
|
+
headers['Content-Type'] = mime
|
|
65
|
+
headers['Cache-Control'] = 'public'
|
|
66
|
+
headers['Expires'] = "#{(Time.now + 1000).utc}"
|
|
67
|
+
[200, headers, [list]]
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Get the a single file or directory listing
|
|
71
|
+
# @param [Hash] context the context for this request
|
|
72
|
+
# @return [Response] the file, listing, or status code
|
|
73
|
+
def do_read(context)
|
|
74
|
+
path = context.uri[2]
|
|
75
|
+
referrer = context.referer
|
|
76
|
+
repos = context.app[:repos_path]
|
|
77
|
+
web = context.app[:web]
|
|
78
|
+
rev = context.query[:rev]
|
|
79
|
+
id = context.uri[3...context.uri.length].join('/')
|
|
80
|
+
info = do_read_info(rev, web, repos, path, id)
|
|
81
|
+
if info == 404
|
|
82
|
+
return 404
|
|
83
|
+
end
|
|
84
|
+
type = info[:@kind]
|
|
85
|
+
if type.eql? 'dir'
|
|
86
|
+
mime = 'text/html'
|
|
87
|
+
list = do_read_listing(web, repos, path, id)
|
|
88
|
+
template = context.app[:template]
|
|
89
|
+
body = template.render(self, list: list, resource: path, id: id, referrer: referrer)
|
|
90
|
+
else
|
|
91
|
+
body = do_read_file(rev, web, repos, path, id)
|
|
92
|
+
if body == 500
|
|
93
|
+
return body
|
|
94
|
+
end
|
|
95
|
+
mime = do_read_mime(rev, web, repos, path, id)
|
|
96
|
+
end
|
|
97
|
+
headers = {}
|
|
98
|
+
headers['Content-Type'] = mime
|
|
99
|
+
headers['Cache-Control'] = 'public'
|
|
100
|
+
headers['Expires'] = "#{(Time.now + 1000).utc}"
|
|
101
|
+
[200, headers, [body]]
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Update the a single file
|
|
105
|
+
# @param [Hash] context the context for this request
|
|
106
|
+
# @return [Response] status code
|
|
107
|
+
def do_update(context)
|
|
108
|
+
path = context.uri[2]
|
|
109
|
+
repos = context.app[:repos_path]
|
|
110
|
+
web = context.app[:web]
|
|
111
|
+
content = context.json
|
|
112
|
+
id = context.uri[3...context.uri.length].join('/')
|
|
113
|
+
if content[:file]
|
|
114
|
+
file = content[:file][:content].match(/base64,(.*)/)[1]
|
|
115
|
+
file = Base64.decode64(file)
|
|
116
|
+
if context.query[:type]
|
|
117
|
+
mime = context.query[:type]
|
|
118
|
+
else
|
|
119
|
+
mime = content[:file][:mime]
|
|
120
|
+
end
|
|
121
|
+
do_update_file(web, repos, path, id, file, content[:message], mime, context.user)
|
|
122
|
+
else
|
|
123
|
+
do_update_file(web, repos, path, id, URI.unescape(content[:updated]), content[:message], context.query[:type], context.user)
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# Proxy method used when routing
|
|
128
|
+
# @param [Array] actions the allowed actions for this URI
|
|
129
|
+
# @param [Hash] context the context for this request
|
|
130
|
+
# @return [Response] a Rack Response triplet, or status code
|
|
131
|
+
def invoke(actions, context)
|
|
132
|
+
return 404 unless context.uri[2]
|
|
133
|
+
case context.action
|
|
134
|
+
when :create
|
|
135
|
+
do_create(context)
|
|
136
|
+
when :read
|
|
137
|
+
if context.uri[3]
|
|
138
|
+
do_read(context)
|
|
139
|
+
else
|
|
140
|
+
do_read_all(context)
|
|
141
|
+
end
|
|
142
|
+
when :update
|
|
143
|
+
do_update(context)
|
|
144
|
+
else
|
|
145
|
+
403
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
data/lib/app/repo/svn.rb
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
require_relative '../repo'
|
|
2
|
+
require 'nori'
|
|
3
|
+
|
|
4
|
+
# Force Nori to convert tag names to Symbols
|
|
5
|
+
$nori = Nori.new :convert_tags_to => lambda { |tag| tag.snakecase.to_sym }
|
|
6
|
+
|
|
7
|
+
module Repo
|
|
8
|
+
# Repo::SVN is a connector for svnserve
|
|
9
|
+
# @author Bryan T. Meyers
|
|
10
|
+
module SVN
|
|
11
|
+
extend Wire::App
|
|
12
|
+
extend Wire::Resource
|
|
13
|
+
extend Repo
|
|
14
|
+
|
|
15
|
+
# Make a new SVN repo
|
|
16
|
+
# @param [String] path the path to the repositories
|
|
17
|
+
# @param [String] repo the new repo name
|
|
18
|
+
# @return [Integer] status code
|
|
19
|
+
def self.do_create_file(path, repo)
|
|
20
|
+
result = 200
|
|
21
|
+
`svnadmin create #{path}/#{repo}`
|
|
22
|
+
if $?.exitstatus != 0
|
|
23
|
+
return 500
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
if $?.exitstatus != 0
|
|
27
|
+
500
|
|
28
|
+
else
|
|
29
|
+
result
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Read a single file
|
|
34
|
+
# @param [String] rev the revision number to access
|
|
35
|
+
# @param [String] web the subdirectory for web content
|
|
36
|
+
# @param [String] path the path to the repositories
|
|
37
|
+
# @param [String] repo the new repo name
|
|
38
|
+
# @param [String] id the relative path to the file
|
|
39
|
+
# @return [String] the file
|
|
40
|
+
def self.do_read_file(rev, web, path, repo, id)
|
|
41
|
+
@options = "--username=#{$environment[:repos_user]} --password=#{$environment[:repos_password]}"
|
|
42
|
+
if rev.nil?
|
|
43
|
+
rev = 'HEAD'
|
|
44
|
+
end
|
|
45
|
+
if web.nil?
|
|
46
|
+
body = `svn cat #{@options} -r #{rev} 'svn://localhost/#{repo}/#{id}'`
|
|
47
|
+
else
|
|
48
|
+
body = `svn cat #{@options} -r #{rev} 'svn://localhost/#{repo}/#{web}/#{id}'`
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
if $?.success?
|
|
52
|
+
body
|
|
53
|
+
else
|
|
54
|
+
500
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Read a directory listing
|
|
59
|
+
# @param [String] web the subdirectory for web content
|
|
60
|
+
# @param [String] path the path to the repositories
|
|
61
|
+
# @param [String] repo the new repo name
|
|
62
|
+
# @param [String] id the relative path to the file
|
|
63
|
+
# @return [Array] the directory listing
|
|
64
|
+
def self.do_read_listing(web, path, repo, id = nil)
|
|
65
|
+
@options = "--username=#{$environment[:repos_user]} --password=#{$environment[:repos_password]}"
|
|
66
|
+
if web.nil?
|
|
67
|
+
if id.nil?
|
|
68
|
+
list = `svn list #{@options} --xml 'svn://localhost/#{repo}'`
|
|
69
|
+
else
|
|
70
|
+
list = `svn list #{@options} --xml 'svn://localhost/#{repo}/#{id}'`
|
|
71
|
+
end
|
|
72
|
+
else
|
|
73
|
+
if id.nil?
|
|
74
|
+
list = `svn list #{@options} --xml 'svn://localhost/#{repo}/#{web}'`
|
|
75
|
+
else
|
|
76
|
+
list = `svn list #{@options} --xml 'svn://localhost/#{repo}/#{web}/#{id}'`
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
unless $?.exitstatus == 0
|
|
80
|
+
return 404
|
|
81
|
+
end
|
|
82
|
+
list = $nori.parse(list)
|
|
83
|
+
list[:lists][:list][:entry]
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Read Metadata for a single file
|
|
87
|
+
# @param [String] rev the revision number to access
|
|
88
|
+
# @param [String] web the subdirectory for web content
|
|
89
|
+
# @param [String] path the path to the repositories
|
|
90
|
+
# @param [String] repo the new repo name
|
|
91
|
+
# @param [String] id the relative path to the file
|
|
92
|
+
# @return [Hash] the metadata
|
|
93
|
+
def self.do_read_info(rev, web, path, repo, id)
|
|
94
|
+
@options = "--username=#{$environment[:repos_user]} --password=#{$environment[:repos_password]}"
|
|
95
|
+
if rev.nil?
|
|
96
|
+
rev = 'HEAD'
|
|
97
|
+
end
|
|
98
|
+
if web.nil?
|
|
99
|
+
info = `svn info #{@options} -r #{rev} --xml 'svn://localhost/#{repo}/#{id}'`
|
|
100
|
+
else
|
|
101
|
+
info = `svn info #{@options} -r #{rev} --xml 'svn://localhost/#{repo}/#{web}/#{id}'`
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
unless $?.exitstatus == 0
|
|
105
|
+
return 404
|
|
106
|
+
end
|
|
107
|
+
info = $nori.parse(info)
|
|
108
|
+
info[:info][:entry]
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Get a file's MIME type
|
|
112
|
+
# @param [String] rev the revision number to access
|
|
113
|
+
# @param [String] web the subdirectory for web content
|
|
114
|
+
# @param [String] path the path to the repositories
|
|
115
|
+
# @param [String] repo the new repo name
|
|
116
|
+
# @param [String] id the relative path to the file
|
|
117
|
+
# @return [String] the MIME type
|
|
118
|
+
def self.do_read_mime(rev, web, path, repo, id)
|
|
119
|
+
@options = "--username=#{$environment[:repos_user]} --password=#{$environment[:repos_password]}"
|
|
120
|
+
if rev.nil?
|
|
121
|
+
rev = 'HEAD'
|
|
122
|
+
end
|
|
123
|
+
if web.nil?
|
|
124
|
+
mime = `svn propget #{@options} -r #{rev} --xml svn:mime-type 'svn://localhost/#{repo}/#{id}'`
|
|
125
|
+
else
|
|
126
|
+
mime = `svn propget #{@options} -r #{rev} --xml svn:mime-type 'svn://localhost/#{repo}/#{web}/#{id}'`
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
unless $?.success?
|
|
130
|
+
return 500
|
|
131
|
+
end
|
|
132
|
+
mime = $nori.parse(mime)
|
|
133
|
+
if mime[:properties].nil?
|
|
134
|
+
'application/octet-stream'
|
|
135
|
+
else
|
|
136
|
+
mime[:properties][:target][:property]
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# Update a single file
|
|
141
|
+
# @param [String] web the subdirectory for web content
|
|
142
|
+
# @param [String] path the path to the repositories
|
|
143
|
+
# @param [String] repo the new repo name
|
|
144
|
+
# @param [String] id the relative path to the file
|
|
145
|
+
# @param [String] content the updated file
|
|
146
|
+
# @param [String] message the commit message
|
|
147
|
+
# @param [String] mime the mime-type to set
|
|
148
|
+
# @param [String] user the Author of this change
|
|
149
|
+
# @return [Integer] status code
|
|
150
|
+
def self.do_update_file(web, path, repo, id, content, message, mime, user)
|
|
151
|
+
@options = "--username=#{$environment[:repos_user]} --password=#{$environment[:repos_password]}"
|
|
152
|
+
status = 500
|
|
153
|
+
`svn checkout #{@options} svn://localhost/#{repo} /tmp/svn/#{repo}`
|
|
154
|
+
if $?.exitstatus == 0
|
|
155
|
+
if web.nil?
|
|
156
|
+
file_path = "/tmp/svn/#{repo}/#{id}"
|
|
157
|
+
else
|
|
158
|
+
file_path = "/tmp/svn/#{repo}/#{web}/#{id}"
|
|
159
|
+
end
|
|
160
|
+
file = File.open(file_path, 'w+')
|
|
161
|
+
file.syswrite(content)
|
|
162
|
+
file.close
|
|
163
|
+
`svn add #{file_path}`
|
|
164
|
+
`svn propset svn:mime-type #{mime} #{file_path}`
|
|
165
|
+
`svn commit #{@options} -m "#{message}" /tmp/svn/#{repo}`
|
|
166
|
+
if $?.exitstatus == 0
|
|
167
|
+
status = 200
|
|
168
|
+
end
|
|
169
|
+
info = `svn info /tmp/svn/#{repo}`
|
|
170
|
+
rev = info.match(/Last Changed Rev: (\d+)/)[1]
|
|
171
|
+
`svn propset --revprop -r #{rev} svn:author '#{user}' /tmp/svn/#{repo}`
|
|
172
|
+
end
|
|
173
|
+
`rm -R /tmp/svn/#{repo}`
|
|
174
|
+
status
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
end
|