sgfa 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.txt +674 -0
- data/README.txt +14 -0
- data/bin/sgfa +15 -0
- data/data/sgfa_web.css +240 -0
- data/lib/sgfa/binder.rb +627 -0
- data/lib/sgfa/binder_fs.rb +203 -0
- data/lib/sgfa/cli/binder.rb +160 -0
- data/lib/sgfa/cli/jacket.rb +299 -0
- data/lib/sgfa/cli.rb +36 -0
- data/lib/sgfa/demo/web_binders.rb +111 -0
- data/lib/sgfa/demo/web_css.rb +60 -0
- data/lib/sgfa/entry.rb +697 -0
- data/lib/sgfa/error.rb +95 -0
- data/lib/sgfa/history.rb +445 -0
- data/lib/sgfa/jacket.rb +556 -0
- data/lib/sgfa/jacket_fs.rb +136 -0
- data/lib/sgfa/lock_fs.rb +141 -0
- data/lib/sgfa/state_fs.rb +342 -0
- data/lib/sgfa/store_fs.rb +214 -0
- data/lib/sgfa/web/base.rb +225 -0
- data/lib/sgfa/web/binder.rb +1190 -0
- data/lib/sgfa.rb +37 -0
- metadata +68 -0
@@ -0,0 +1,111 @@
|
|
1
|
+
#
|
2
|
+
# Simple Group of Filing Applications
|
3
|
+
# Demo of the web interface to Binder
|
4
|
+
#
|
5
|
+
# Copyright (C) 2015 by Graham A. Field.
|
6
|
+
#
|
7
|
+
# See LICENSE.txt for licensing information.
|
8
|
+
#
|
9
|
+
# This program is distributed WITHOUT ANY WARRANTY; without even the
|
10
|
+
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
11
|
+
|
12
|
+
require 'rack'
|
13
|
+
|
14
|
+
require_relative '../binder_fs'
|
15
|
+
require_relative '../error'
|
16
|
+
require_relative '../web/binder'
|
17
|
+
|
18
|
+
module Sgfa
|
19
|
+
module Demo
|
20
|
+
|
21
|
+
#####################################################################
|
22
|
+
# Demo of the web interface to {Binder}s using {BinderFs} with the first
|
23
|
+
# part of the path being the Binder name. The user is taken from the
|
24
|
+
# REMOTE_USER with no groups.
|
25
|
+
#
|
26
|
+
class WebBinders
|
27
|
+
|
28
|
+
#####################################
|
29
|
+
# New web binder demo
|
30
|
+
#
|
31
|
+
# @param dir [String] The directory
|
32
|
+
# @param css [String] URL for the style sheet
|
33
|
+
#
|
34
|
+
def initialize(dir, css)
|
35
|
+
@path = dir
|
36
|
+
@css = css
|
37
|
+
@app = Sgfa::Web::Binder.new
|
38
|
+
end # def initialize()
|
39
|
+
|
40
|
+
|
41
|
+
#####################################
|
42
|
+
# Rack call
|
43
|
+
#
|
44
|
+
# @param env [Hash] The rack environment
|
45
|
+
# @return [Array] Response, Headers, Body
|
46
|
+
#
|
47
|
+
def call(env)
|
48
|
+
bnd = Sgfa::BinderFs.new
|
49
|
+
env['sgfa.user'] = env['REMOTE_USER'].dup
|
50
|
+
env['sgfa.groups'] = []
|
51
|
+
env['sgfa.css'] = @css
|
52
|
+
|
53
|
+
# get binder name
|
54
|
+
old_path = env['PATH_INFO']
|
55
|
+
old_script = env['SCRIPT_NAME']
|
56
|
+
path = old_path.split('/')
|
57
|
+
return not_found if path.empty?
|
58
|
+
bnam = Rack::Utils.unescape(path[1])
|
59
|
+
return not_found if bnam[0] == '.' || bnam[0] == '_'
|
60
|
+
|
61
|
+
# Adjust SCRIPT_NAME and PATH_INFO
|
62
|
+
env['PATH_INFO'] = '/' + path[2..-1].join('/')
|
63
|
+
new_script = old_script + path[0,2].join('/')
|
64
|
+
env['SCRIPT_NAME'] = new_script.dup
|
65
|
+
|
66
|
+
# Open binder
|
67
|
+
begin
|
68
|
+
bnd.open(File.join(@path, bnam))
|
69
|
+
rescue Sgfa::Error::NonExistent => exp
|
70
|
+
return not_found
|
71
|
+
end
|
72
|
+
|
73
|
+
# call app
|
74
|
+
begin
|
75
|
+
env['sgfa.binder'] = bnd
|
76
|
+
env['sgfa.binder.url'] = new_script.dup
|
77
|
+
env['sgfa.binder.name'] = bnam
|
78
|
+
ret = @app.call(env)
|
79
|
+
ensure
|
80
|
+
bnd.close
|
81
|
+
env['PATH_INFO'] = old_path
|
82
|
+
env['SCRIPT_NAME'] = old_script
|
83
|
+
end
|
84
|
+
|
85
|
+
return ret
|
86
|
+
|
87
|
+
rescue => exc
|
88
|
+
err = []
|
89
|
+
err.push "<html><head><title>error</title></head>\n<body>\n"
|
90
|
+
err.push "<p>" + Rack::Utils.escape_html(exc.class.name) + "</p>\n"
|
91
|
+
err.push "<p>" + Rack::Utils.escape_html(exc.message) + "</p>\n"
|
92
|
+
exc.backtrace.each do |bt|
|
93
|
+
err.push "<p>" + Rack::Utils.escape_html(bt) + "</p>\n"
|
94
|
+
end
|
95
|
+
err.push "</body>\n</html>\n"
|
96
|
+
return ['404', {'Content-Type' => 'text/html'}, err]
|
97
|
+
end # def call()
|
98
|
+
|
99
|
+
|
100
|
+
#####################################
|
101
|
+
# Generic not found error
|
102
|
+
def not_found()
|
103
|
+
[404, {'Content-Type' => 'text/plain'}, ['Not found.']]
|
104
|
+
end # def not_found
|
105
|
+
|
106
|
+
end # def WebBinders
|
107
|
+
|
108
|
+
end # module Demo
|
109
|
+
end # module Sgfa
|
110
|
+
|
111
|
+
|
@@ -0,0 +1,60 @@
|
|
1
|
+
#
|
2
|
+
# Simple Group of Filing Applications
|
3
|
+
# Demo server for
|
4
|
+
#
|
5
|
+
# Copyright (C) 2015 by Graham A. Field.
|
6
|
+
#
|
7
|
+
# See LICENSE.txt for licensing information.
|
8
|
+
#
|
9
|
+
# This program is distributed WITHOUT ANY WARRANTY; without even the
|
10
|
+
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
11
|
+
|
12
|
+
require 'time'
|
13
|
+
|
14
|
+
module Sgfa
|
15
|
+
module Demo
|
16
|
+
|
17
|
+
|
18
|
+
#####################################################################
|
19
|
+
# Simple Rack app which serves a static CSS file and passes all other
|
20
|
+
# requests along to another app.
|
21
|
+
class WebCss
|
22
|
+
|
23
|
+
#####################################
|
24
|
+
# Initial setup
|
25
|
+
#
|
26
|
+
# @param css [String] The CSS to serve
|
27
|
+
# @param path [String] Where to serve it
|
28
|
+
# @param app [#call] The app which gets everything else
|
29
|
+
#
|
30
|
+
def initialize(css, path, app)
|
31
|
+
@app = app
|
32
|
+
@css = css
|
33
|
+
@path = path
|
34
|
+
@header = {
|
35
|
+
'Content-Type' => 'text/css; charset=utf-8',
|
36
|
+
'Content-Length' => @css.bytesize.to_s,
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
#####################################
|
42
|
+
# The Rack app
|
43
|
+
#
|
44
|
+
# @param env [Hash] The Rack environment
|
45
|
+
# @return [Array] Rack return of status, headers, and body
|
46
|
+
#
|
47
|
+
def call(env)
|
48
|
+
if env['PATH_INFO'] == @path && env['REQUEST_METHOD'] == 'GET'
|
49
|
+
exp = (Time.now + 60*60).rfc2822
|
50
|
+
@header['Expires'] = exp
|
51
|
+
[200, @header, [@css]]
|
52
|
+
else
|
53
|
+
@app.call(env)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end # class WebCss
|
58
|
+
|
59
|
+
end # module Demo
|
60
|
+
end # module Sgfa
|