infod 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/infod.rb +2 -3
- data/infod/Es.rb +31 -67
- data/infod/{W/source.rb → Es/code.rb} +6 -10
- data/infod/Es/css.rb +21 -0
- data/infod/{W → Es}/csv.rb +0 -0
- data/infod/Es/du.rb +16 -0
- data/infod/{W → Es}/feed.rb +13 -11
- data/infod/Es/filter.rb +75 -0
- data/infod/Es/find.rb +20 -0
- data/infod/Es/fs.rb +145 -136
- data/infod/Es/glob.rb +22 -0
- data/infod/Es/grep.rb +61 -0
- data/infod/Es/groonga.rb +47 -56
- data/infod/Es/html.rb +271 -0
- data/infod/Es/image.rb +114 -0
- data/infod/Es/in.rb +68 -0
- data/infod/Es/index.rb +183 -0
- data/infod/{W → Es}/json.rb +28 -4
- data/infod/Es/kv.rb +60 -0
- data/infod/Es/ls.rb +58 -0
- data/infod/Es/mail.rb +87 -0
- data/infod/Es/man.rb +112 -0
- data/infod/Es/mime.rb +59 -0
- data/infod/Es/out.rb +52 -0
- data/infod/{W/page.rb → Es/pager.rb} +7 -3
- data/infod/Es/pdf.rb +19 -0
- data/infod/Es/rdf.rb +35 -0
- data/infod/Es/schema.rb +99 -0
- data/infod/Es/search.rb +24 -0
- data/infod/Es/sh.rb +21 -0
- data/infod/{W → Es}/text.rb +26 -14
- data/infod/H.rb +15 -29
- data/infod/H/audio.rb +19 -0
- data/infod/H/blog.rb +15 -0
- data/infod/{W → H}/cal.rb +2 -31
- data/infod/H/edit.rb +88 -0
- data/infod/{W/examine/examine.rb → H/facets.rb} +17 -17
- data/infod/{W → H}/forum.rb +1 -0
- data/infod/{W/examine/sw.rb → H/hf.rb} +12 -12
- data/infod/H/histogram.rb +78 -0
- data/infod/H/mail.rb +92 -0
- data/infod/{W/chat.rb → H/microblog.rb} +21 -16
- data/infod/H/threads.rb +77 -0
- data/infod/H/time.rb +131 -0
- data/infod/H/who.rb +30 -0
- data/infod/{W → H}/wiki.rb +0 -0
- data/infod/K.rb +28 -60
- data/infod/N.rb +151 -74
- data/infod/Rb.rb +3 -3
- data/infod/Th.rb +27 -101
- data/infod/Th/404.rb +29 -36
- data/infod/Th/500.rb +36 -5
- data/infod/Th/GET.rb +48 -118
- data/infod/Th/POST.rb +31 -11
- data/infod/Th/perf.rb +37 -0
- data/infod/Th/util.rb +89 -0
- data/infod/Y.rb +24 -7
- data/infod/infod.rb +2 -3
- metadata +92 -64
- data/infod/Es/redis.rb +0 -3
- data/infod/Es/sqlite.rb +0 -3
- data/infod/Th/local.rb +0 -22
- data/infod/W.rb +0 -34
- data/infod/W/audio.rb +0 -56
- data/infod/W/blog.rb +0 -3
- data/infod/W/color.rb +0 -28
- data/infod/W/core.rb +0 -77
- data/infod/W/css.rb +0 -24
- data/infod/W/du.rb +0 -35
- data/infod/W/edit.rb +0 -8
- data/infod/W/examine/exhibit.rb +0 -34
- data/infod/W/examine/hist.rb +0 -55
- data/infod/W/examine/history.rb +0 -19
- data/infod/W/examine/normal.rb +0 -31
- data/infod/W/examine/protovis.rb +0 -30
- data/infod/W/examine/time/graph.rb +0 -86
- data/infod/W/examine/time/line.rb +0 -24
- data/infod/W/find.rb +0 -24
- data/infod/W/grep.rb +0 -27
- data/infod/W/html.rb +0 -143
- data/infod/W/image.rb +0 -61
- data/infod/W/kv.rb +0 -66
- data/infod/W/ls.rb +0 -50
- data/infod/W/mail.rb +0 -248
- data/infod/W/pdf.rb +0 -16
- data/infod/W/post.rb +0 -9
- data/infod/W/rdf.rb +0 -32
- data/infod/W/schema.rb +0 -172
- data/infod/W/search.rb +0 -33
- data/infod/W/shell.rb +0 -30
- data/infod/W/table.rb +0 -87
- data/infod/W/tree.rb +0 -26
- data/infod/W/vfs.rb +0 -175
data/infod/Es/schema.rb
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
#watch __FILE__
|
2
|
+
class E
|
3
|
+
=begin
|
4
|
+
www) http://data.whats-your.name
|
5
|
+
|
6
|
+
local) wget http://whats-your.name/schema.txt
|
7
|
+
x-www-browser http://localhost/schema
|
8
|
+
|
9
|
+
rebuild)
|
10
|
+
1) fetch
|
11
|
+
) RDF schema pointer document
|
12
|
+
curl http://prefix.cc/popular/all.file.txt > prefix.txt
|
13
|
+
) RDF usage data
|
14
|
+
curl http://data.whats-your.name/schema/gromgull.gz | zcat > properties.txt
|
15
|
+
2) analyze
|
16
|
+
irb> E.cacheSchemas
|
17
|
+
.. E.indexSchemas
|
18
|
+
|
19
|
+
schema missing? publish and contact prefix.cc,
|
20
|
+
see also ideas at http://www.w3.org/2013/04/vocabs/
|
21
|
+
|
22
|
+
=end
|
23
|
+
|
24
|
+
UsageWeight = 'http://schema.whats-your.name/usageFrequency'
|
25
|
+
SchemasRDFa = %w{http://schema.org/docs/schema_org_rdfa.html}.map &:E
|
26
|
+
|
27
|
+
def E.cacheSchemas
|
28
|
+
E.schemaDocs.map &:cacheSchema
|
29
|
+
# rapper2 is failing at RDFa autodiscovery, import them again
|
30
|
+
SchemasRDFa.map{|s|
|
31
|
+
s.ttl.w `rapper -i rdfa -o turtle #{s.uri}`
|
32
|
+
s.ef.w s.ttl.graphFromFile,true}
|
33
|
+
end
|
34
|
+
|
35
|
+
def E.indexSchemas
|
36
|
+
g = {}
|
37
|
+
E.schemaDocs.map(&:ef).flatten.map{|d|d.graphFromFile g}
|
38
|
+
'/schema/schema.txt'.E.w g.sort_by{|u,r|r[UsageWeight]}.map{|u,r|
|
39
|
+
[(r[UsageWeight]||0),
|
40
|
+
u,
|
41
|
+
r[Label],
|
42
|
+
r[DC+'description'],
|
43
|
+
r[Purl+'dc/elements/1.1/description'],
|
44
|
+
r[RDFs+'comment']
|
45
|
+
].join(' ').gsub("\n"," ") if u.path?
|
46
|
+
}.compact.join "\n"
|
47
|
+
end
|
48
|
+
|
49
|
+
def cacheSchema
|
50
|
+
# write Turtle
|
51
|
+
ttl.w(`rapper -o turtle #{uri}`) unless ttl.e
|
52
|
+
|
53
|
+
# except indexed docs & huge dbpedia/wordnet dumps
|
54
|
+
unless ef.e || ttl.do{|t| t.e && t.size > 256e3}
|
55
|
+
g = ttl.graphFromFile # parse
|
56
|
+
g.map{|u,r| # each resource
|
57
|
+
E.schemaWeights[u].do{|w| # grab stats
|
58
|
+
r[UsageWeight] = w }}
|
59
|
+
ef.w g,true # write annotated graph
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def E.schemaWeights
|
64
|
+
@schemaWeights ||=
|
65
|
+
(data = '/properties.txt'.E
|
66
|
+
(puts "download\ncurl http://data.whats-your.name/schema/gromgull.gz | zcat > predicates.txt"; exit) unless data.e
|
67
|
+
w = {}
|
68
|
+
data.read.each_line{|e|
|
69
|
+
e.match(/(\d+)[^<]+<([^>]+)>/).do{|r|
|
70
|
+
w[r[2]] = r[1].to_i }}
|
71
|
+
w)
|
72
|
+
end
|
73
|
+
|
74
|
+
def E.schemaDocs
|
75
|
+
@schemaDocs ||=
|
76
|
+
(source = E['http://prefix.cc/popular/all.file.txt']
|
77
|
+
mirror = E['/prefix.txt']
|
78
|
+
(mirror.e ? mirror : source). # select schema-pointers doc
|
79
|
+
read.split(/\n/).grep(/^[^#]/). # each uncommented line
|
80
|
+
map{|t| t.split(/\t/)[1].E }. # parse to resource pointer
|
81
|
+
concat SchemasRDFa) # schema list
|
82
|
+
end
|
83
|
+
|
84
|
+
fn '/schema/GET',->e,r{
|
85
|
+
if (q = r.q['q']) && !q.empty?
|
86
|
+
search = "grep -i #{q.sh} #{'/schema/schema.txt'.E.d} | head -n 255"
|
87
|
+
found = `#{search}`.to_utf8.lines.to_a.map{|i|
|
88
|
+
c,u,t = i.split ' ',3
|
89
|
+
c = c.to_i
|
90
|
+
[("<b>#{c}</b>" unless c.zero?),
|
91
|
+
" <a href='#{u}'>#{F['abbrURI'][u]}</a> ",
|
92
|
+
t,"<br>\n"]}
|
93
|
+
end
|
94
|
+
(H ['<html><body>',(H.css '/css/search'),(H.css '/css/schema'),(H.js '/js/search'),
|
95
|
+
F['view/search/form'][r.q,r], found,
|
96
|
+
'<br>sources ',{_: :a, href: 'http://prefix.cc', c: 'prefix.cc'},' and ',{_: :a, href: SchemasRDFa[0], c: 'schema.org'},
|
97
|
+
]).hR}
|
98
|
+
|
99
|
+
end
|
data/infod/Es/search.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
class E
|
2
|
+
|
3
|
+
fn '/search/GET',->e,r{
|
4
|
+
r.q['graph'] = 'roonga'
|
5
|
+
e.response
|
6
|
+
}
|
7
|
+
|
8
|
+
fn 'head/search',->d,e{[{_: :title, c: e.q['q']},(Fn 'head.formats',e)]}
|
9
|
+
|
10
|
+
fn 'view/search',->d,e{
|
11
|
+
[H.css('/css/search'),H.js('/js/search'),
|
12
|
+
(Fn 'view/search/form',e.q,e),
|
13
|
+
(Fn 'view/page',d,e)]}
|
14
|
+
|
15
|
+
fn 'view/search/form',-> q=nil,e { q||={}
|
16
|
+
[{:class => :form,
|
17
|
+
c: {_: :form, action: e['REQUEST_PATH'],
|
18
|
+
c: [{_: :input, name: :q, value: q['q']}, # search box
|
19
|
+
q.except('q','start'). # new query & offset for this search
|
20
|
+
map{|a,s|
|
21
|
+
{_: :input, name: a, value: s, :type => :hidden}}]}},
|
22
|
+
{class: :space}]}
|
23
|
+
|
24
|
+
end
|
data/infod/Es/sh.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
class E
|
2
|
+
|
3
|
+
# util, URI prefix, cleaner -> tripleStream
|
4
|
+
def triplrStdOut e,f='/',g=/^\s*(.*?)\s*$/,a=sh
|
5
|
+
|
6
|
+
`#{e} #{a}|grep :`.each_line{|i|
|
7
|
+
|
8
|
+
# split keys from vals
|
9
|
+
i = i.split /:/
|
10
|
+
|
11
|
+
yield uri,
|
12
|
+
(f + (i[0].match(g)||[0,i[0]])[1]. # id cleaner
|
13
|
+
gsub(/\s/,'_').gsub(/\//,'-').gsub(/[\(\)]+/,'')), # predicate
|
14
|
+
i.tail.join(':').strip.do{|v|v.match(/^[0-9\.]+$/) ? v.to_f : v} # object
|
15
|
+
}
|
16
|
+
nil
|
17
|
+
rescue
|
18
|
+
nil
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
data/infod/{W → Es}/text.rb
RENAMED
@@ -2,11 +2,16 @@
|
|
2
2
|
#watch __FILE__
|
3
3
|
|
4
4
|
class String
|
5
|
+
|
5
6
|
def hrefs i=false
|
7
|
+
# keep consuming URL chars when:
|
8
|
+
# ( to ) - ")" won't match without an opener, such as when URL is placed in ()s
|
9
|
+
# , or . followed by non-whitespace
|
10
|
+
# not URI-wrapping chars, phrase/sentence terminators , . or whitespace
|
6
11
|
(partition /(https?:\/\/(\([^)]*\)|[,.]\S|[^\s),.”\'\"<>\]])+)/).do{|p|
|
7
12
|
p[0].gsub('<','<').gsub('>','>')+
|
8
13
|
(p[1].empty?&&''||'<a rel=untyped href='+p[1]+'>'+p[1].do{|p|
|
9
|
-
i && p.match(/(gif|
|
14
|
+
i && p.match(/(gif|jpe?g|png|tiff)$/i) &&
|
10
15
|
"<img src=#{p}>" || p
|
11
16
|
}+'</a>')+
|
12
17
|
(p[2].empty?&&''||p[2].hrefs)
|
@@ -25,9 +30,10 @@ class E
|
|
25
30
|
[(H.once e,'text',(H.css '/css/text')),
|
26
31
|
d.values.map{|v|
|
27
32
|
v[Content].do{|c|
|
33
|
+
b = E.cs
|
28
34
|
{class: :text,
|
29
|
-
c: [{_: :a, href: v.url+'?view', c: v.label, style: "background-color:" +
|
30
|
-
{_: :pre, c: c }]}}}]}
|
35
|
+
c: [{_: :a, href: v.url+'?view', c: v.label, style: "background-color:" + b},
|
36
|
+
{_: :pre, c: c, style: "border-color:" + b}]}}}]}
|
31
37
|
|
32
38
|
F['view/'+MIMEtype+'application/word']= F['view/monospace']
|
33
39
|
F['view/'+MIMEtype+'blob'] = F['view/monospace']
|
@@ -38,29 +44,32 @@ class E
|
|
38
44
|
style: 'background-color:#000;padding:2em;color:#fff;float:left;font-family: "Courier New", "DejaVu Sans Mono", monospace; font-size: 13px; line-height: 13px',
|
39
45
|
c: [{_: :a,
|
40
46
|
style: 'color:#0f0;font-size:1.1em;font-weight:bold',
|
41
|
-
c: r.
|
42
|
-
|
43
|
-
'<br>',r[Content]]}}}
|
47
|
+
href: r.url, c: r.uri},'<br>',
|
48
|
+
r[Content]]}}}
|
44
49
|
|
45
|
-
fn 'view/title',->d,e{
|
46
|
-
|
50
|
+
fn 'view/title',->d,e{
|
51
|
+
i = F['view/title/item']
|
52
|
+
[d.map{|u,r|[i.(r,e),' ']},
|
53
|
+
(H.once e,'title',(H.css '/css/title'))
|
54
|
+
]}
|
47
55
|
|
48
|
-
fn 'view/title/item',->r,e{
|
56
|
+
fn 'view/title/item',->r,e{
|
57
|
+
{_: :a, class: :title, href: r.E.url,
|
58
|
+
c: r[Title] || (Fn 'abbrURI', r.uri)}}
|
49
59
|
|
50
60
|
# linebreak-delimited list of URIs
|
51
61
|
def triplrUriList
|
52
|
-
open(d).readlines.map{|l|
|
62
|
+
open(d).readlines.grep(/^[^#]/).map{|l|
|
53
63
|
l = l.chomp
|
54
|
-
yield uri, '/
|
55
|
-
yield l, '/
|
64
|
+
yield uri, '/rel', l
|
65
|
+
yield l, '/rev', uri
|
56
66
|
}
|
57
67
|
end
|
58
68
|
|
59
|
-
# list of uris in a .u doc
|
60
69
|
def uris
|
61
70
|
graph.keys.map &:E
|
62
71
|
end
|
63
|
-
|
72
|
+
|
64
73
|
def triplrANSI
|
65
74
|
yield uri, Content, `cat #{sh} | aha`
|
66
75
|
end
|
@@ -89,6 +98,9 @@ class E
|
|
89
98
|
gsub(/\n+/,"\n")}. # collapse empty space
|
90
99
|
intersperse(' '),"\n"]},"\n"]}.join} # collate
|
91
100
|
|
101
|
+
F['view/text/plain']=->d,e{
|
102
|
+
{_: :pre, c: F[Render+'text/plain'][d,e]}}
|
103
|
+
|
92
104
|
fn Render+'text/uri',->d,_=nil{d.keys.join "\n"}
|
93
105
|
|
94
106
|
end
|
data/infod/H.rb
CHANGED
@@ -1,29 +1,15 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
end
|
17
|
-
|
18
|
-
class H
|
19
|
-
|
20
|
-
def H.js a,inline=false
|
21
|
-
p=a+'.js'
|
22
|
-
inline ? {_: :script, c: p.E.r} :
|
23
|
-
{_: :script, type: "text/javascript", src: p} end
|
24
|
-
|
25
|
-
def H.once e,n,*h
|
26
|
-
return if e[n]
|
27
|
-
e[n]=true
|
28
|
-
h end
|
29
|
-
end
|
1
|
+
%w{
|
2
|
+
audio
|
3
|
+
cal
|
4
|
+
edit
|
5
|
+
facets
|
6
|
+
forum
|
7
|
+
hf
|
8
|
+
histogram
|
9
|
+
mail
|
10
|
+
microblog
|
11
|
+
threads
|
12
|
+
time
|
13
|
+
who
|
14
|
+
wiki
|
15
|
+
}.each{|r|require_relative 'H/'+r}
|
data/infod/H/audio.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
class E
|
2
|
+
|
3
|
+
fn 'set/audio',->d,e,m{d.take.select{|e|e.ext.match AudioFile}}
|
4
|
+
fn 'set/video',->d,e,m{d.take.select{|e|e.ext.match VideoFile}}
|
5
|
+
|
6
|
+
AudioK = {}
|
7
|
+
%w{Album-Movie-Show_title Lead_performers-Soloists Title-songname-content_description}.map{|a|Audio + a}.concat(['uri',Stat+'mtime', Stat+'size']).map{|p|AudioK[p] = true}
|
8
|
+
|
9
|
+
fn 'view/audio',->d,e{
|
10
|
+
d = d.dup
|
11
|
+
d.delete_if{|p,o| !p.match AudioFile }
|
12
|
+
d.values.map{|r| r.delete_if{|p,o| !AudioK[p] }}
|
13
|
+
|
14
|
+
[(H.once e, :mu, (H.js '/js/mu')),
|
15
|
+
(H.once e, :audio, (H.js '/js/audio'), (H.css '/css/audio'), {id: :rand, c: :r}, {id: :jump, c: '→'}, {id: :info, target: :_blank, _: :a},
|
16
|
+
{_: e.q.has_key?('video') ? :video : :audio, id: :media, controls: true}), '<br>',
|
17
|
+
F['view/table'][d,e]]}
|
18
|
+
|
19
|
+
end
|
data/infod/H/blog.rb
ADDED
data/infod/{W → H}/cal.rb
RENAMED
@@ -1,19 +1,7 @@
|
|
1
1
|
#watch __FILE__
|
2
2
|
class E
|
3
|
-
|
4
|
-
|
5
|
-
send(*f){|s,p,o|
|
6
|
-
yield *({'CreationDate' => true,
|
7
|
-
'Date' => true,
|
8
|
-
RSS+'pubDate' => true,
|
9
|
-
Date => true,
|
10
|
-
Purl+'dc/elements/1.1/date' => true,
|
11
|
-
Atom+'published' => true,
|
12
|
-
Atom+'updated' => true
|
13
|
-
}[p] ?
|
14
|
-
[s,
|
15
|
-
Date,
|
16
|
-
Time.parse(o).utc.iso8601] :[s,p,o])} end
|
3
|
+
|
4
|
+
# TODO test rww.io/data.fm linked-data calendar apps for compatibility with our backend (and fix our backend if it doesn't work, obiously..)
|
17
5
|
|
18
6
|
fn 'cal/day',->{Time.now.strftime '%Y/%m/%d/'}
|
19
7
|
fn 'cal/month',->{Time.now.strftime '%Y/%m/'}
|
@@ -26,12 +14,6 @@ class E
|
|
26
14
|
def day; as Fn 'cal/day' end
|
27
15
|
def month; as Fn 'cal/month' end
|
28
16
|
|
29
|
-
fn 'graph/cal',->d,e,m{
|
30
|
-
DateTime.parse(e['s']||'2011-03-03').
|
31
|
-
upto(e['f'].do{|f|DateTime.parse f} || DateTime.now).
|
32
|
-
map{|d|m[d.iso8601]={Date=>[d]}}
|
33
|
-
m }
|
34
|
-
|
35
17
|
fn 'table/year',->d{ m={}
|
36
18
|
d.map{|u,r|
|
37
19
|
r[Date][0].do{|t|
|
@@ -97,14 +79,3 @@ class E
|
|
97
79
|
]}}
|
98
80
|
|
99
81
|
end
|
100
|
-
|
101
|
-
class Object
|
102
|
-
def time?
|
103
|
-
(self.class == Time) || (self.class == DateTime)
|
104
|
-
end
|
105
|
-
def to_time
|
106
|
-
time? ? self : Time.parse(self)
|
107
|
-
rescue
|
108
|
-
nil
|
109
|
-
end
|
110
|
-
end
|
data/infod/H/edit.rb
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
watch __FILE__
|
2
|
+
class E
|
3
|
+
|
4
|
+
fn 'protograph/editable',->resource,env,graph{
|
5
|
+
Fn 'protograph/_',resource,env,graph}
|
6
|
+
|
7
|
+
fn 'graph/editable',->resource,env,graph{
|
8
|
+
resource.fromStream graph, :triplrFsStore
|
9
|
+
[Title,Creator,Content].map{|u|graph[u]||={}}}
|
10
|
+
|
11
|
+
# show resource w/ links into editor
|
12
|
+
fn 'view/edit',->g,e{
|
13
|
+
[(H.once e, 'edit', (H.css '/css/edit')),
|
14
|
+
g.map{|uri,s| uri && s &&
|
15
|
+
(url = uri.E.localURL e
|
16
|
+
{class: :resource,
|
17
|
+
c: [{_: :a, class: :uri, id: uri, c: uri, href: url, title: 'view '+uri},
|
18
|
+
{_: :a, class: :addField, c: '+add field', href: url+'?graph=_&view=editP'},
|
19
|
+
s.map{|p,o|
|
20
|
+
{class: :property,
|
21
|
+
c: [{_: :a, class: :edit, c: :edit,
|
22
|
+
href: e['REQUEST_PATH']+'?graph=editable&filter=p&view=editPO&p=uri,'+CGI.escape(p)},
|
23
|
+
(case p
|
24
|
+
when 'uri'
|
25
|
+
{_: :a, class: :uri, c: p, href: p}
|
26
|
+
when Content
|
27
|
+
{_: :pre, c: o}
|
28
|
+
else
|
29
|
+
o.html
|
30
|
+
end)]}}]})}]}
|
31
|
+
|
32
|
+
# select or mint a property to edit
|
33
|
+
fn 'view/editP',->g,e{
|
34
|
+
[(H.once e, 'edit', (H.css '/css/edit')),
|
35
|
+
|
36
|
+
# core properties
|
37
|
+
[Date,Title,Creator,Content,Label].map{|p|
|
38
|
+
{_: :a, href: p, c: p.label+' '}},
|
39
|
+
|
40
|
+
# URI-typed input
|
41
|
+
{_: :form, action: e['REQUEST_PATH'], method: :GET,
|
42
|
+
c: [{_: :input, type: :url, name: :p, pattern: '^http.*$', size: 53},
|
43
|
+
|
44
|
+
# editor arguments
|
45
|
+
{ filter: :p,
|
46
|
+
graph: :editable,
|
47
|
+
view: :editPO}.map{|n,v|
|
48
|
+
{_: :input, type: :hidden, name: n, value: v}},
|
49
|
+
|
50
|
+
# submit
|
51
|
+
{_: :input, type: :submit, value: 'property'},
|
52
|
+
]},
|
53
|
+
# schema search-engine
|
54
|
+
#{_: :iframe, style: 'width: 100%;height:42ex', src: 'http://data.whats-your.name'}
|
55
|
+
]}
|
56
|
+
|
57
|
+
# edit triples
|
58
|
+
fn 'view/editPO',->g,e{
|
59
|
+
|
60
|
+
p = e.q['p'].expand
|
61
|
+
|
62
|
+
# triple -> input
|
63
|
+
triple = ->s,p,o{
|
64
|
+
|
65
|
+
# triple identifier
|
66
|
+
i = (s.E.concatURI p).concatURI E(p).literal o
|
67
|
+
|
68
|
+
[(case p
|
69
|
+
when Content
|
70
|
+
{_: :textarea, name: i, c: o, rows: 24, cols: 80}
|
71
|
+
else
|
72
|
+
{_: :input, name: i, value: o}
|
73
|
+
end
|
74
|
+
)]}
|
75
|
+
|
76
|
+
{_: :form, name: :editor, method: :POST, action: e['REQUEST_PATH'],
|
77
|
+
c: [(H.once e, 'edit', (H.css '/css/edit')),
|
78
|
+
{_: :h2, c: p},
|
79
|
+
# existing entries
|
80
|
+
g.map{|s,r| r[p].do{|p| p.map{|o|
|
81
|
+
triple[s,p,o]}.cr}},
|
82
|
+
# new entry
|
83
|
+
triple[e['uri'],p,''],' ',
|
84
|
+
{_: :input, type: :submit, value: 'save'},
|
85
|
+
{_: :a, c: ' cancel', href: e['REQUEST_PATH']+'?view=edit&graph=editable'}
|
86
|
+
]}}
|
87
|
+
|
88
|
+
end
|