infod 0.0.3.2 → 0.0.3.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/infod +1 -1
- data/infod.rb +14 -9
- data/infod/404.rb +19 -6
- data/infod/500.rb +2 -2
- data/infod/GET.rb +18 -16
- data/infod/HTTP.rb +5 -7
- data/infod/POST.rb +27 -20
- data/infod/audio.rb +1 -1
- data/infod/blog.rb +23 -6
- data/infod/cal.rb +2 -2
- data/infod/code.rb +2 -2
- data/infod/constants.rb +5 -3
- data/infod/csv.rb +5 -5
- data/infod/edit.rb +24 -28
- data/infod/facets.rb +4 -4
- data/infod/feed.rb +12 -12
- data/infod/forum.rb +1 -1
- data/infod/fs.rb +57 -109
- data/infod/graph.rb +37 -17
- data/infod/grep.rb +4 -4
- data/infod/groonga.rb +14 -14
- data/infod/histogram.rb +5 -5
- data/infod/html.rb +41 -38
- data/infod/image.rb +7 -9
- data/infod/index.rb +13 -43
- data/infod/infod.rb +14 -9
- data/infod/lambda.rb +32 -20
- data/infod/ls.rb +32 -9
- data/infod/mail.rb +104 -94
- data/infod/man.rb +6 -6
- data/infod/microblog.rb +12 -12
- data/infod/mime.rb +8 -15
- data/infod/names.rb +89 -235
- data/infod/rdf.rb +9 -15
- data/infod/schema.rb +17 -17
- data/infod/text.rb +58 -15
- data/infod/threads.rb +12 -9
- data/infod/time.rb +5 -6
- metadata +41 -59
- data/infod/HEAD.rb +0 -23
- data/infod/find.rb +0 -19
- data/infod/glob.rb +0 -25
- data/infod/kv.rb +0 -56
- data/infod/page.rb +0 -19
- data/infod/postscript.rb +0 -26
- data/infod/ruby.rb +0 -57
- data/infod/sh.rb +0 -19
- data/infod/webid.rb +0 -0
- data/infod/wiki.rb +0 -18
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 06750f111d49bb2b62f28cd18bc35dd5212dc0ac
|
4
|
+
data.tar.gz: 7ee2db920696465b43201741aa28e6ecaf64af41
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 03d0d7ae6b88af73a4d5054e2736764d46d5e3247284bcbda919c811182ab0bdbf4e2ef37ccd5fdd8228f4435f3bc6f23311f6f6ac41a9f70016338e4bc6a01c
|
7
|
+
data.tar.gz: ff95efae2b1690cd8f244360e903d1f9a7ea287a2450cdcb85e418b1f444eed54d9601819f4a266897ba0409711ad5af572f984f65a9b076395c2cf690a26cdb
|
data/bin/infod
CHANGED
data/infod.rb
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
%w{
|
2
|
+
cgi
|
3
|
+
date
|
4
|
+
digest/sha1
|
5
|
+
fileutils
|
6
|
+
json
|
7
|
+
linkeddata
|
8
|
+
mail
|
9
|
+
nokogiri
|
10
|
+
open-uri
|
11
|
+
pathname
|
12
|
+
rack
|
13
|
+
shellwords}.map{|r|require r}
|
14
|
+
|
1
15
|
%w{
|
2
16
|
constants
|
3
17
|
lambda
|
@@ -13,34 +27,25 @@ csv
|
|
13
27
|
edit
|
14
28
|
facets
|
15
29
|
feed
|
16
|
-
find
|
17
30
|
forum
|
18
31
|
fs
|
19
32
|
GET
|
20
|
-
glob
|
21
33
|
graph
|
22
34
|
groonga
|
23
|
-
HEAD
|
24
35
|
histogram
|
25
36
|
html
|
26
37
|
HTTP
|
27
38
|
image
|
28
39
|
index
|
29
|
-
kv
|
30
40
|
ls
|
31
41
|
mail
|
32
42
|
man
|
33
43
|
microblog
|
34
44
|
names
|
35
|
-
page
|
36
45
|
POST
|
37
|
-
postscript
|
38
46
|
rdf
|
39
|
-
ruby
|
40
47
|
schema
|
41
|
-
sh
|
42
48
|
text
|
43
49
|
threads
|
44
50
|
time
|
45
|
-
wiki
|
46
51
|
}.map{|e|require_relative e}
|
data/infod/404.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
class
|
1
|
+
class R
|
2
2
|
|
3
3
|
E404 = 'req/'+HTTP+'404'
|
4
4
|
|
@@ -13,18 +13,20 @@ r.map{|k,v| s[Header + k] = k == 'uri' ? v : [v] }
|
|
13
13
|
%w{CHARSET LANGUAGE ENCODING}.map{|a|
|
14
14
|
s[Header+'ACCEPT_'+a] = [r.accept_('_' + a)]}
|
15
15
|
s[Header+'ACCEPT'] = [r.accept]
|
16
|
-
s[Type] = [
|
16
|
+
s[Type] = [R[HTTP+'Response']]
|
17
17
|
s[HTTP+'statusCodeValue'] = [404]
|
18
|
-
s[Header+'HTTP_HOST'] = [
|
19
|
-
s[Edit] = [
|
18
|
+
s[Header+'HTTP_HOST'] = [R['http://' + s[Header+'HTTP_HOST'][0]]] if s[Header+'HTTP_HOST']
|
19
|
+
s[Edit] = [R[r['REQUEST_PATH']+'?graph=create']]
|
20
20
|
s['#query'] = [r.q]
|
21
21
|
s['#seeAlso'] = [e.parent,*e.a('*').glob]
|
22
22
|
r.q['view'] = '404'
|
23
23
|
|
24
24
|
[404,{'Content-Type'=> r.format},[e.render(r.format,g,r)]]}
|
25
|
-
|
25
|
+
|
26
|
+
F['/cache/GET'] = F[E404]
|
27
|
+
|
26
28
|
fn 'view/404',->d,e{
|
27
|
-
[H.css('/css/404'),{_: :style, c: "a {background-color:#{
|
29
|
+
[H.css('/css/404'),{_: :style, c: "a {background-color:#{R.cs}}"},
|
28
30
|
d.html]}
|
29
31
|
|
30
32
|
# a resource-placeholder graph
|
@@ -32,4 +34,15 @@ s[HTTP+'statusCodeValue'] = [404]
|
|
32
34
|
m[d.uri] = {}
|
33
35
|
rand.to_s.h}
|
34
36
|
|
37
|
+
def checkURIs
|
38
|
+
r = uris.map{|u|
|
39
|
+
c = [`curl -IsA 404? "#{u}"`.lines.to_a[0].match(/\d{3}/)[0].to_i,u] # HEAD
|
40
|
+
puts c.join ' '
|
41
|
+
c } # status, uri tuple
|
42
|
+
puts "\n\n"
|
43
|
+
r.map{|c|
|
44
|
+
# show anomalies
|
45
|
+
puts c.join(' ') unless c[0] == 200 }
|
46
|
+
end
|
47
|
+
|
35
48
|
end
|
data/infod/500.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#watch __FILE__
|
2
|
-
class
|
2
|
+
class R
|
3
3
|
|
4
4
|
Errors ||= {}
|
5
5
|
|
@@ -44,7 +44,7 @@ h1 {padding:.2em; background-color:#f00; color:#fff; margin:0}
|
|
44
44
|
div {display:inline}
|
45
45
|
table {border-spacing:0;margin:0}
|
46
46
|
b {background-color:#eee;color:#500;padding:.1em .3em .1em .3em}
|
47
|
-
.frag {font-weight:bold; color:#000; background-color:#{
|
47
|
+
.frag {font-weight:bold; color:#000; background-color:#{R.cs}}
|
48
48
|
td.space {background-color:#ddd}
|
49
49
|
td.message {background-color:#009;color:#fff}
|
50
50
|
td.path {text-align:right}
|
data/infod/GET.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
class
|
1
|
+
class R
|
2
2
|
|
3
3
|
Apache = ENV['apache']
|
4
4
|
Nginx = ENV['nginx']
|
@@ -21,6 +21,14 @@ class E
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
+
def HEAD
|
25
|
+
self.GET.do{|s,h,b|[s,h,[]]}
|
26
|
+
end
|
27
|
+
|
28
|
+
def OPTIONS
|
29
|
+
[200,{},[]]
|
30
|
+
end
|
31
|
+
|
24
32
|
def getFile
|
25
33
|
@r['ETag'] = [m,size].h
|
26
34
|
maybeSend mimeP,->{self}
|
@@ -52,25 +60,19 @@ class E
|
|
52
60
|
@r['ETag'] ||= [@r.q['view'].do{|v|F['view/' + v] && v}, graphID, @r.format, Watch].h
|
53
61
|
|
54
62
|
maybeSend @r.format, ->{
|
55
|
-
|
56
|
-
|
57
|
-
r
|
58
|
-
if r.e # exists
|
63
|
+
|
64
|
+
r = R '/cache/view/' + @r['ETag'].dive
|
65
|
+
if r.e # exists?
|
59
66
|
r
|
60
67
|
else
|
61
|
-
|
62
|
-
#
|
63
|
-
c = E '/E/graph/' + graphID.dive
|
64
|
-
if c.e # exists
|
68
|
+
c = R '/cache/model/' + graphID.dive
|
69
|
+
if c.e # exists?
|
65
70
|
m = c.r true
|
66
71
|
else
|
67
|
-
# construct
|
68
|
-
|
69
|
-
# cache
|
70
|
-
c.w m,true
|
72
|
+
(g && F['graph/' + g] || F['graph/'])[self, @r.q,m] # construct
|
73
|
+
c.w m,true # cache
|
71
74
|
end
|
72
|
-
|
73
|
-
r.w render @r.format, m, @r
|
75
|
+
r.w render @r.format, m, @r # construct -> cache
|
74
76
|
end }
|
75
77
|
end
|
76
78
|
|
@@ -85,7 +87,7 @@ class E
|
|
85
87
|
h.update({'Cache-Control' => 'no-transform'}) if m.match /^(audio|image|video)/ # already compresed
|
86
88
|
|
87
89
|
# frontend-specific handlers
|
88
|
-
b.class ==
|
90
|
+
b.class == R ? (Nginx ? # nginx chosen?
|
89
91
|
[c,h.update({'X-Accel-Redirect' => '/fs' + b.path}),[]] : # Nginx handler
|
90
92
|
Apache ? # Apache chosen?
|
91
93
|
[c,h.update({'X-Sendfile' => b.d}),[]] : # Apache handler
|
data/infod/HTTP.rb
CHANGED
@@ -1,14 +1,12 @@
|
|
1
1
|
#watch __FILE__
|
2
|
-
|
2
|
+
class R
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
def E.call e
|
7
|
-
e.extend Th # add HTTP utility functions to environment table
|
4
|
+
def R.call e
|
5
|
+
e.extend Th # HTTP utility functions
|
8
6
|
dev # see if watched files were changed
|
9
7
|
e['HTTP_X_FORWARDED_HOST'].do{|h| e['SERVER_NAME'] = h }
|
10
8
|
path = CGI.unescape e['REQUEST_PATH'].force_encoding('UTF-8').gsub '+','%2B'
|
11
|
-
resource =
|
9
|
+
resource = R['http://'+e['SERVER_NAME']+path]
|
12
10
|
|
13
11
|
if resource.inside
|
14
12
|
e['uri'] = resource.uri
|
@@ -66,7 +64,7 @@ module Th
|
|
66
64
|
# Accept formats
|
67
65
|
accept.sort.reverse.map{|q,mimes|
|
68
66
|
mimes.map{|mime|
|
69
|
-
return mime if
|
67
|
+
return mime if R::F[R::Render+mime]}}
|
70
68
|
'text/html'
|
71
69
|
end
|
72
70
|
|
data/infod/POST.rb
CHANGED
@@ -1,31 +1,38 @@
|
|
1
|
-
watch __FILE__
|
2
|
-
class
|
1
|
+
#watch __FILE__
|
2
|
+
class R
|
3
3
|
|
4
4
|
def POST
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
# custom handler lookup cascade
|
6
|
+
pathSegment.do{|path|
|
7
|
+
lambdas = path.cascade.map{|p| p.uri.t + 'POST' }
|
8
|
+
['http://'+@r['SERVER_NAME'],""].map{|h| lambdas.map{|p|
|
9
|
+
F[h + p].do{|fn| fn[self,@r].do{|r|
|
10
|
+
$stdout.puts [r[0],'http://'+@r['SERVER_NAME']+@r['REQUEST_URI'],@r['HTTP_USER_AGENT'],@r['HTTP_REFERER'],@r.format].join ' '
|
11
|
+
return r
|
12
|
+
}}}}}
|
13
|
+
basicPOST
|
14
|
+
end
|
15
|
+
def basicPOST
|
16
|
+
return [303,{'Location'=>uri},[]]
|
17
|
+
case @r['CONTENT_TYPE']
|
9
18
|
when /^application\/x-www-form-urlencoded/
|
10
19
|
changed = false
|
11
|
-
(Rack::Request.new @r).params.map{|k,v|
|
12
|
-
s
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
end
|
21
|
-
end
|
20
|
+
(Rack::Request.new @r).params.map{|k,v| s, p, tripleA = JSON.parse CGI.unescape k
|
21
|
+
s = s.R
|
22
|
+
pp = s.predicatePath p
|
23
|
+
o = v.match(/\A(\/|http)[\S]+\Z/) ? v.R : F['cleanHTML'][v]
|
24
|
+
tripleB = pp.objectPath(o)[0]
|
25
|
+
if tripleA.to_s != tripleB.to_s
|
26
|
+
tripleA && tripleA.R.do{|t| t.delete if t.e }
|
27
|
+
s[p] = o unless o.class==String && o.empty?
|
28
|
+
changed = true
|
22
29
|
end}
|
23
30
|
if changed
|
24
31
|
g = {}
|
25
32
|
fromStream g, :triplrDoc
|
26
|
-
if g.empty?
|
27
|
-
ef.
|
28
|
-
else
|
33
|
+
if g.empty? # no triples left
|
34
|
+
ef.delete
|
35
|
+
else # snapshot to graph-doc
|
29
36
|
ef.w g, true
|
30
37
|
end
|
31
38
|
end
|
data/infod/audio.rb
CHANGED
data/infod/blog.rb
CHANGED
@@ -1,29 +1,46 @@
|
|
1
1
|
#watch __FILE__
|
2
|
-
class
|
2
|
+
class R
|
3
3
|
|
4
|
-
F['
|
4
|
+
F['/blog/post/POST'] = -> d,e {
|
5
|
+
name = URI.escape (Rack::Request.new d.env).params['name'].gsub /[?#\s\/]/,'_'
|
6
|
+
doc = 'http://'+e['SERVER_NAME']+Time.now.strftime('/%Y/%m/')+name
|
7
|
+
post = doc.R.a '#'
|
8
|
+
post[Type] = R[SIOCt+'BlogPost']
|
9
|
+
post[Title] = name
|
10
|
+
edit = "?prototype=sioct:BlogPost&graph=edit"
|
11
|
+
[303,{'Location' => doc + edit},[]]}
|
5
12
|
|
6
|
-
|
13
|
+
F['/blog/post/GET'] = -> d,e {
|
14
|
+
[200,{'Content-Type'=>'text/html'},
|
15
|
+
[H(['name',
|
16
|
+
{_: :form, method: :POST,
|
17
|
+
c: [{_: :input, name: :name, style: "font-size:1.6em;width:48ex"},
|
18
|
+
{_: :input, type: :submit, value: ' go '}
|
19
|
+
]}])]]}
|
7
20
|
|
8
|
-
}
|
21
|
+
F['view/'+SIOCt+'BlogPost']=->g,e{F['example/blogview'][g,e]}
|
9
22
|
|
10
23
|
F['example/blogview']=->g,e{
|
11
24
|
g.map{|u,r|
|
12
|
-
case u
|
25
|
+
case u # match against URIs for customized view
|
13
26
|
when /artery.wbur/ # compact whitespace a bit
|
14
27
|
r[Content] = {class: :WBUR, c: [{_: :style, c: ".WBUR p {margin:0}"},r[Content]]}
|
15
28
|
F['view/base'][{u => r},e,false]
|
29
|
+
|
16
30
|
when /boston\.com/ # crop sharebuttons
|
17
31
|
(Nokogiri::HTML.parse r[Content][0]).css('p')[0].do{|p|r[Content]=p.inner_html}
|
18
32
|
F['view/base'][{u => r},e,false]
|
33
|
+
|
19
34
|
when /flickr/
|
20
35
|
r[Content]
|
36
|
+
|
21
37
|
when /reddit/ # minimal view
|
22
38
|
F['view/'+SIOCt+'BoardPost'][{u => r},e]
|
39
|
+
|
23
40
|
when /universalhub/ # logo + trim spacehogging tagjunk
|
24
41
|
c = Nokogiri::HTML.fragment r[Content][0]
|
25
42
|
c.css('section').map{|x|x.remove}
|
26
|
-
{c: [{_: :a, href: r['http://purl.org/rss/1.0/link'][0].
|
43
|
+
{c: [{_: :a, href: r['http://purl.org/rss/1.0/link'][0].R.uri,
|
27
44
|
c: [{_: :img, src: '/logos/uhub.png',style: 'position:absolute;top:-93px'},
|
28
45
|
{_: :h2, style: 'color:#000;margin:0',c: r[Title]}]},c.to_s],
|
29
46
|
style: 'float:left;max-width:40em;position:relative;background-color:#fff;border-color:#eee;margin-top:93px;margin-right:.3em;padding-top:0;border-style:dotted;border-width:.3em;border-radius:0 .8em .8em .8em'}
|
data/infod/cal.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#watch __FILE__
|
2
|
-
class
|
2
|
+
class R
|
3
3
|
|
4
4
|
fn 'req/day',->e,r{
|
5
5
|
[303, {'Location'=> e.day.uri + r.q.except('y').qs}, []]}
|
@@ -51,7 +51,7 @@ class E
|
|
51
51
|
|
52
52
|
fn 'view/month',->d,e{
|
53
53
|
[(d.delete :time).do{|month|
|
54
|
-
{_: :b, c: month.strftime('%B'),style: "color: #{
|
54
|
+
{_: :b, c: month.strftime('%B'),style: "color: #{R.cs}"}},
|
55
55
|
F['view/t'][d,e,'day','day-terminate']]}
|
56
56
|
|
57
57
|
fn 'view/day-terminate',->d,e{
|
data/infod/code.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
class
|
1
|
+
class R
|
2
2
|
|
3
3
|
def triplrSourceCode
|
4
4
|
m = mime.split(/\//)[-1].sub(/^x-/,'')
|
@@ -10,7 +10,7 @@ class E
|
|
10
10
|
end
|
11
11
|
|
12
12
|
fn 'view/code',->d,e{[{_: :style, c: 'body{background-color:white;color:black}'},
|
13
|
-
d.values.map{|r|[r.
|
13
|
+
d.values.map{|r|[r.R.do{|e|[{_: :a,name: e.uri},e.html(e.base,true)]},'<br>',
|
14
14
|
r[Content]]}]}
|
15
15
|
|
16
16
|
# ls /usr/share/source-highlight/*.lang | xargs -i basename {} .lang | tr "\n" " "
|
data/infod/constants.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
|
-
class
|
1
|
+
class R
|
2
2
|
|
3
3
|
FSbase = `pwd`.chomp ; BaseLen = FSbase.size
|
4
|
-
S = /\._/ # data path-separator
|
5
4
|
|
6
5
|
W3 = 'http://www.w3.org/'
|
7
6
|
Purl = 'http://purl.org/'
|
@@ -46,10 +45,13 @@ class E
|
|
46
45
|
Prefix={
|
47
46
|
"dc" => DC,
|
48
47
|
"foaf" => FOAF,
|
49
|
-
"rdf" =>
|
48
|
+
"rdf" => RDFns,
|
50
49
|
"rdfs" => RDFs,
|
51
50
|
"sioc" => SIOC,
|
51
|
+
"sioct" => SIOCt,
|
52
52
|
"stat" => Stat,
|
53
53
|
}
|
54
54
|
|
55
|
+
attr_reader :uri
|
56
|
+
|
55
57
|
end
|
data/infod/csv.rb
CHANGED
@@ -1,19 +1,19 @@
|
|
1
1
|
#watch __FILE__
|
2
|
-
class
|
2
|
+
class R
|
3
3
|
|
4
4
|
# CSV -> tripleStream
|
5
5
|
def triplrCSV d
|
6
6
|
d = @r.q['delim']||d
|
7
7
|
open(node).readlines.map{|l|l.chomp.split(d) rescue []}.do{|lines|
|
8
8
|
lines[0].do{|fields| # ok, we have at least one line..
|
9
|
-
yield uri+'#', Type,
|
9
|
+
yield uri+'#', Type, R[CSV+'Table']
|
10
10
|
yield uri+'#', CSV+'rowCount', lines.size
|
11
|
-
yield uri+'#', COGS+'View',
|
11
|
+
yield uri+'#', COGS+'View', R[uri+'?view=csv']
|
12
12
|
lines[1..-1].each_with_index{|row,line|
|
13
13
|
row.each_with_index{|field,i|
|
14
14
|
id = uri + '#row:' + line.to_s
|
15
15
|
yield id, fields[i], field
|
16
|
-
yield id, Type,
|
16
|
+
yield id, Type, R[CSV+'Row']
|
17
17
|
}}}}
|
18
18
|
end
|
19
19
|
|
@@ -24,7 +24,7 @@ class E
|
|
24
24
|
r[Type].do{|t|
|
25
25
|
t.class == Array &&
|
26
26
|
t.map(&:maybeURI).member?(CSV+'Row')})}
|
27
|
-
#
|
27
|
+
# eat the type-tag
|
28
28
|
d.values.map{|r|r.delete Type}
|
29
29
|
|
30
30
|
[F['view/p'][d,e],
|
data/infod/edit.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
watch __FILE__
|
2
|
-
class
|
1
|
+
#watch __FILE__
|
2
|
+
class R
|
3
3
|
|
4
4
|
Prototypes = {
|
5
5
|
SIOCt+'MicroblogPost' => [Content],
|
@@ -16,7 +16,7 @@ class E
|
|
16
16
|
fn 'view/create',->g,e{
|
17
17
|
[{_: :style, c: 'a {display:block;font-size:2em}'},{_: :b, c: :type},
|
18
18
|
Prototypes.map{|t,ps|
|
19
|
-
{_: :a, href: e['REQUEST_PATH']+'?graph=edit&prototype='+(
|
19
|
+
{_: :a, href: e['REQUEST_PATH']+'?graph=edit&prototype='+(URI.escape t.shorten), c: t.label}}]}
|
20
20
|
|
21
21
|
# editable triples
|
22
22
|
F['protograph/edit'] = -> e,env,g {
|
@@ -25,6 +25,7 @@ class E
|
|
25
25
|
rand.to_s.h}
|
26
26
|
|
27
27
|
fn 'graph/edit',->e,env,g{
|
28
|
+
puts "graph.edit #{e}"
|
28
29
|
e.fromStream g, :triplrDoc} # add fs-sourced triples
|
29
30
|
|
30
31
|
=begin HTML <form> RDF editor
|
@@ -35,47 +36,42 @@ class E
|
|
35
36
|
fn 'view/edit',->g,e{
|
36
37
|
|
37
38
|
# render a triple
|
38
|
-
triple = ->s,p,o{
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
end
|
53
|
-
),"<br>\n"]
|
54
|
-
end}
|
55
|
-
|
39
|
+
triple = ->s,p,o{ # http://dev.w3.org/html5/markup/input.html#input
|
40
|
+
spo = o && s.R.predicatePath(p).objectPath(o)[0].uri
|
41
|
+
t = CGI.escape [s,p,spo].to_json
|
42
|
+
[(case p.R.uri
|
43
|
+
when Content
|
44
|
+
[{_: :textarea, name: t, c: o, rows: 16, cols: 80},
|
45
|
+
'<br>',o]
|
46
|
+
when Date
|
47
|
+
{_: :input, name: t, type: :datetime, value: !o || o.empty? && Time.now.iso8601 || o}
|
48
|
+
else
|
49
|
+
{_: :input, name: t, value: o, size: 54}
|
50
|
+
end
|
51
|
+
),"<br>\n"]}
|
52
|
+
|
56
53
|
ps = [] # predicates to go editable on
|
57
|
-
e.q['prototype'].do{|pr|
|
54
|
+
e.q['prototype'].do{|pr| pr = pr.expand
|
58
55
|
Prototypes[pr].do{|v|ps.concat v }} # prototype imports
|
59
56
|
e.q['predicate'].do{|p|ps.push p } # explicit predicate
|
60
57
|
|
61
|
-
[
|
58
|
+
[H.css('/css/html'),
|
62
59
|
{_: :form, name: :editor, method: :POST, action: e['REQUEST_PATH'],
|
63
60
|
|
64
61
|
c: [{_: :a, class: :edit, c: '+add field',
|
65
62
|
href: e['uri']+'?graph=blank&view=addP', style: 'background-color:#0f0;border-radius:5em;color:#000;padding:.5em'},
|
66
63
|
g.map{|s,r| # subject
|
67
|
-
uri = s.
|
68
|
-
{_: :table,
|
64
|
+
uri = s.R.localURL e
|
65
|
+
{_: :table, class: :html,
|
69
66
|
c: [{_: :tr, c: {_: :td, colspan: 2, c: {_: :a, class: :uri, id: s, c: s, href: uri}}},
|
70
|
-
{_: :input, type: :hidden, name: s.E.concatURI(Edit.E).concatURI(E['/']), value: e['uri']+'?graph=edit'},
|
71
67
|
r.keys.-([Edit]).concat(ps).uniq.map{|p| # resource + prototype/initialize predicates
|
72
68
|
{_: :tr,
|
73
|
-
c: [{_: :td, c: {_: :a, title: p, href: p, c: p.abbrURI}}, # property
|
69
|
+
c: [{_: :td, class: :key, c: {_: :a, title: p, href: p, c: p.abbrURI}}, # property
|
74
70
|
{_: :td,
|
75
71
|
c: [r[p].do{|o| # objects
|
76
72
|
(o.class == Array ? o : [o]).map{|o| # each object
|
77
73
|
triple[s,p,o]}}, # existing triples
|
78
|
-
triple[s,p,
|
74
|
+
triple[s,p,nil]]}]}}]}}, # new triple
|
79
75
|
{_: :input, type: :submit, value: 'save'}]}]}
|
80
76
|
|
81
77
|
# select a property to edit
|