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/image.rb
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
#watch __FILE__
|
2
|
+
class E
|
3
|
+
|
4
|
+
def triplrImage &f
|
5
|
+
triplrStdOut 'exiftool', EXIF, &f
|
6
|
+
end
|
7
|
+
|
8
|
+
# export EXIF to RDF-in-JSON (recursive)
|
9
|
+
def exif
|
10
|
+
take.map{|g|
|
11
|
+
if g.uri.match /(jpe?g|gif|png)$/i
|
12
|
+
e = g.ef
|
13
|
+
if !e.e || e.m < g.m
|
14
|
+
g.ef.w g.fromStream({},:triplrImage), true
|
15
|
+
puts "EXIF #{g} #{g.ef.size} bytes"
|
16
|
+
end
|
17
|
+
end}
|
18
|
+
end
|
19
|
+
|
20
|
+
fn 'req/scaleImage',->e,r{
|
21
|
+
i = [e,e.pathSegment].compact.find(&:f)
|
22
|
+
if i && i.size > 0
|
23
|
+
size = r.q['px'].to_i.min(8).max(4096)
|
24
|
+
stat = i.node.stat
|
25
|
+
id = [stat.ino,stat.mtime,size].h.dive
|
26
|
+
path = E['/E/image/'+id+'.png']
|
27
|
+
if !path.e
|
28
|
+
path.dirname.mk
|
29
|
+
if i.mimeP.match(/^video/)
|
30
|
+
`ffmpegthumbnailer -s #{size} -i #{i.sh} -o #{path.sh}`
|
31
|
+
else
|
32
|
+
`gm convert #{i.sh} -thumbnail "#{size}x#{size}" #{path.sh}`
|
33
|
+
end
|
34
|
+
end
|
35
|
+
path.e ? (path.env r).getFile : F[E404][e,r]
|
36
|
+
else
|
37
|
+
F[E404][e,r]
|
38
|
+
end}
|
39
|
+
|
40
|
+
fn 'view/img',->i,_{
|
41
|
+
[i.values.map{|i|
|
42
|
+
[{_: :a, href: i.url,
|
43
|
+
c: {_: :img,
|
44
|
+
style:'float:left;max-width:61.8%',
|
45
|
+
src: i.url}},
|
46
|
+
i.html]},
|
47
|
+
(H.css '/css/img')]}
|
48
|
+
|
49
|
+
fn 'view/th',->i,e{
|
50
|
+
i.map{|u,i| u.match(/(gif|jpe?g|png|tiff)$/i) &&
|
51
|
+
{_: :a, href: i.url+'?triplr=triplrImage&view=img',
|
52
|
+
c: {_: :img, src: i.url+'?y=scaleImage&px=233'}}}}
|
53
|
+
|
54
|
+
F['view/'+MIMEtype+'image/gif'] = F['view/th']
|
55
|
+
F['view/'+MIMEtype+'image/jpeg']= F['view/th']
|
56
|
+
F['view/'+MIMEtype+'image/png'] = F['view/th']
|
57
|
+
|
58
|
+
# display just the images found in content
|
59
|
+
fn 'view/imgs',->m,e{
|
60
|
+
|
61
|
+
# height argument
|
62
|
+
h = e.q['h'].do{|h|
|
63
|
+
h.match(/^[0-9]+$/).do{|_|'height:'+h+'px'}}
|
64
|
+
|
65
|
+
# visited images
|
66
|
+
seen={}
|
67
|
+
|
68
|
+
# extension-based filter
|
69
|
+
x=->i{i&&i.match(/(jpe?g|gif|png)$/i)&&i}
|
70
|
+
|
71
|
+
[(H.once e,:mu,H.js('/js/mu')),H.js('/js/images'),
|
72
|
+
m.values.map{|v|
|
73
|
+
# CSS selector-based search
|
74
|
+
[[*v[Content]].map{|c| c.class == String &&
|
75
|
+
(Nokogiri::HTML.parse(c).do{|c|
|
76
|
+
[# <img> elements
|
77
|
+
c.css('img').map{|i|i['src']}.compact,
|
78
|
+
# <a> elements with image extensions
|
79
|
+
c.css('a').map{|i|i['href']}.select(&x)]
|
80
|
+
})},
|
81
|
+
# check subject URI for image extension
|
82
|
+
x.(v.uri),
|
83
|
+
# check object URIs for image extension
|
84
|
+
(v.respond_to?(:values) &&
|
85
|
+
v.values.flatten.map{|v|
|
86
|
+
v.respond_to?(:uri) && v.uri
|
87
|
+
}.select(&x))
|
88
|
+
].flatten.uniq.compact.map{|s|
|
89
|
+
# view
|
90
|
+
{uri: s,
|
91
|
+
# img and link to containing resource
|
92
|
+
c: ->{"<a href='#{v.uri.to_s.do{|u|u.path? ? u : u.E.url}}'><img style='float:left;#{h}' src='#{s}'></a>"}}}}.flatten.map{|i|
|
93
|
+
# show and mark as seen
|
94
|
+
!seen[i[:uri]] &&
|
95
|
+
(seen[i[:uri]] = true
|
96
|
+
i[:c].())}]}
|
97
|
+
|
98
|
+
def E.c; '#%06x' % rand(16777216) end
|
99
|
+
def E.cs; '#%02x%02x%02x' % F['color/hsv2rgb'][rand*6,1,1] end
|
100
|
+
|
101
|
+
fn 'color/hsv2rgb',->h,s,v{
|
102
|
+
i = h.floor
|
103
|
+
f = h - i
|
104
|
+
p = v * (1 - s)
|
105
|
+
q = v * (1 - (s * f))
|
106
|
+
t = v * (1 - (s * (1 - f)))
|
107
|
+
r,g,b=[[v,t,p],
|
108
|
+
[q,v,p],
|
109
|
+
[p,v,t],
|
110
|
+
[p,q,v],
|
111
|
+
[t,p,v],
|
112
|
+
[v,p,q]][i].map{|q|q*255.0}}
|
113
|
+
|
114
|
+
end
|
data/infod/Es/in.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
#watch __FILE__
|
2
|
+
class E
|
3
|
+
|
4
|
+
# Graph -> tripleStream -> Graph
|
5
|
+
def fromStream m,*i
|
6
|
+
send(*i) do |s,p,o|
|
7
|
+
m[s] = {'uri' => s} unless m[s].class == Hash
|
8
|
+
m[s][p] ||= []
|
9
|
+
m[s][p].push o unless m[s][p].member? o
|
10
|
+
end; m
|
11
|
+
end
|
12
|
+
|
13
|
+
# default proto-graph
|
14
|
+
# mint graph identifier
|
15
|
+
# any graph setup (:g variable mutation) is preserved
|
16
|
+
fn 'protograph/',->e,q,g{
|
17
|
+
set = (F['set/' + q['set']] || F['set/'])[e,q,g]
|
18
|
+
set.map{|u| g[u.uri] ||= u if u.class == E } if set.class == Array
|
19
|
+
# unique fingerprint for graph
|
20
|
+
[F['docsID'][g],
|
21
|
+
F['triplr'][e,q],
|
22
|
+
q.has_key?('nocache').do{|_|rand}
|
23
|
+
].h}
|
24
|
+
|
25
|
+
# default graph
|
26
|
+
# filesystem storage
|
27
|
+
fn 'graph/',->e,q,m{
|
28
|
+
triplr = F['triplr'][e,q]
|
29
|
+
m.values.map{|r|
|
30
|
+
(r.env e.env).graphFromFile m, triplr if r.class == E }}
|
31
|
+
|
32
|
+
fn 'docsID',->g{
|
33
|
+
g.sort.map{|u,r|
|
34
|
+
[u, r.respond_to?(:m) && r.m]}.h}
|
35
|
+
|
36
|
+
fn 'triplr',->e,q{
|
37
|
+
t = q['triplr']
|
38
|
+
t && e.respond_to?(t) && t || :triplrMIME }
|
39
|
+
|
40
|
+
# document-set
|
41
|
+
fn 'set/',->e,q,_{
|
42
|
+
s = []
|
43
|
+
s.concat e.docs
|
44
|
+
e.pathSegment.do{|p| s.concat p.docs }
|
45
|
+
s }
|
46
|
+
|
47
|
+
def triplrMIME &b
|
48
|
+
mimeP.do{|mime|
|
49
|
+
yield uri,E::Type,(E MIMEtype+mimeP)
|
50
|
+
(MIMEsource[mimeP]||
|
51
|
+
MIMEsource[mimeP.split(/\//)[0]]).do{|s|
|
52
|
+
send *s,&b }}
|
53
|
+
end
|
54
|
+
|
55
|
+
def graphFromFile g={}, triplr=:triplrMIME
|
56
|
+
g.mergeGraph r(true) if ext=='e' # JSON -> graph
|
57
|
+
[:triplrInode, # filesystem data
|
58
|
+
triplr].# format-specific tripleStream emitter
|
59
|
+
each{|i| fromStream g,i } # tripleStream -> Graph
|
60
|
+
g
|
61
|
+
end
|
62
|
+
|
63
|
+
def graph g={}
|
64
|
+
docs.map{|d|d.graphFromFile g} # tripleStream -> graph
|
65
|
+
g
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
data/infod/Es/index.rb
ADDED
@@ -0,0 +1,183 @@
|
|
1
|
+
#watch __FILE__
|
2
|
+
class E
|
3
|
+
|
4
|
+
# POSIX-fs based index of triples
|
5
|
+
#
|
6
|
+
|
7
|
+
# index a triple
|
8
|
+
def index p,o
|
9
|
+
p = p.E
|
10
|
+
indexEdit p, (o.class == E ? o : p.literal(o)), nil
|
11
|
+
end
|
12
|
+
|
13
|
+
# index a triple - no input type-normalization
|
14
|
+
def indexEdit p,o,a
|
15
|
+
return if @noIndex
|
16
|
+
p.pIndex.noIndex[o,self,a]
|
17
|
+
end
|
18
|
+
def noIndex
|
19
|
+
@noIndex = 1
|
20
|
+
self
|
21
|
+
end
|
22
|
+
|
23
|
+
# reachable graph along named predicate
|
24
|
+
def walk p, g={}, v={}
|
25
|
+
graph g # cumulative graph
|
26
|
+
v[uri] = true # visited mark
|
27
|
+
|
28
|
+
rel = g[uri].do{|s|s[p]} ||[]
|
29
|
+
rev = (p.E.po self) ||[]
|
30
|
+
|
31
|
+
rel.concat(rev).map{|r|
|
32
|
+
v[r.uri] || (r.E.walk p,g,v)}
|
33
|
+
|
34
|
+
g
|
35
|
+
end
|
36
|
+
|
37
|
+
# subtree traverse
|
38
|
+
fn 'set/subtree',->d,r,m{
|
39
|
+
c =(r['c'].do{|c|c.to_i + 1} || 3).max(100) # one extra for start of next-page
|
40
|
+
o = r['d'] =~ /^a/ ? :asc : :desc # direction
|
41
|
+
('/'.E.take c, o, d.uri).do{|s| # take subtree
|
42
|
+
desc, asc = o == :desc ? # orient pagination hints
|
43
|
+
[s.pop, s[0]] : [s[0], s.pop]
|
44
|
+
m['prev'] = {'uri' => 'prev', 'url' => desc.url,'d' => 'desc'}
|
45
|
+
m['next'] = {'uri' => 'next', 'url' => asc.url, 'd' => 'asc'}
|
46
|
+
s }}
|
47
|
+
|
48
|
+
# subtree traverse index on p+o cursor
|
49
|
+
fn 'set/index',->d,r,m,f=:rangePO{
|
50
|
+
top = (f == :rangeP ? d : r['p']).expand.E
|
51
|
+
count = r['c'] &&
|
52
|
+
r['c'].to_i.max(1000)+1 || 22
|
53
|
+
dir = r['d'] &&
|
54
|
+
r['d'].match(/^(a|de)sc$/) &&
|
55
|
+
r['d'].to_sym ||
|
56
|
+
:desc
|
57
|
+
|
58
|
+
(top.send f, count, dir, r['offset'],(d if f == :rangePO)).do{|s|
|
59
|
+
# pagination pointers
|
60
|
+
a,b = s[0], s.size > 1 && s.pop
|
61
|
+
desc,asc = r['d'] && r['d']=='asc' && [a,b]||[b,a]
|
62
|
+
# insert pointers in response-graph
|
63
|
+
m['prev']={'uri' => 'prev','url' => d.url,'d' => 'desc','offset' => desc.uri} if desc
|
64
|
+
m['next']={'uri' => 'next','url' => d.url,'d' => 'asc', 'offset' => asc.uri} if asc
|
65
|
+
s }}
|
66
|
+
|
67
|
+
fn 'set/indexP',->d,r,m{Fn 'set/index',d,r,m,:rangeP}
|
68
|
+
F['set/indexPO'] = F['set/index']
|
69
|
+
|
70
|
+
# predicate index
|
71
|
+
def pIndex
|
72
|
+
prependURI '/index/'
|
73
|
+
end
|
74
|
+
|
75
|
+
# predicate-object index
|
76
|
+
def poIndex o
|
77
|
+
pIndex.concatURI o
|
78
|
+
end
|
79
|
+
|
80
|
+
# predicate-object index lookup
|
81
|
+
def po o
|
82
|
+
pIndex[o.class == E ? o : literal(o)]
|
83
|
+
end
|
84
|
+
|
85
|
+
# range query - predicate
|
86
|
+
def rangeP n=8,d=:desc,s=nil,o=nil
|
87
|
+
pIndex.subtree(n,d,s).map &:ro
|
88
|
+
end
|
89
|
+
|
90
|
+
# range query - predicate-object
|
91
|
+
def rangePO n=8,d=:desc,s=nil,o
|
92
|
+
poIndex(o).subtree(n,d,s).map &:ro
|
93
|
+
end
|
94
|
+
|
95
|
+
# E -> [node]
|
96
|
+
def subtree *a
|
97
|
+
u.take *a
|
98
|
+
end
|
99
|
+
|
100
|
+
# E -> [E]
|
101
|
+
def take *a
|
102
|
+
no.take(*a).map &:E
|
103
|
+
end
|
104
|
+
|
105
|
+
# random leaf
|
106
|
+
def randomLeaf
|
107
|
+
c.empty? && self || c.r.randomLeaf
|
108
|
+
end
|
109
|
+
|
110
|
+
fn 'set/randomLeaf',->d,e,m{[d.randomLeaf]}
|
111
|
+
fn 'req/randomLeaf',->e,r{[302, {Location: e.randomLeaf.uri},[]]}
|
112
|
+
|
113
|
+
|
114
|
+
# enumerate unique predicates in index
|
115
|
+
fn '/index/GET',->e,r{
|
116
|
+
e.pathSegment.uri.match(/^\/index$/) &&
|
117
|
+
(H [{_: :style, c: "a {font-size:3em;display:block}
|
118
|
+
a:hover {background-color:#00f}"},
|
119
|
+
'/index'.E.take.map{|e|e.uri[6..-1].unpath.do{|p|{_: :a, href: '/@'+URI.escape(p.uri)+'?set=indexP&view=page&v=linkPO&c=12', c: p}}}]).hR}
|
120
|
+
|
121
|
+
# p/o index-traversal pointers
|
122
|
+
fn 'view/linkPO',->d,e{
|
123
|
+
p = e['uri']
|
124
|
+
[(H.css '/css/index'),(H.js '/js/search'),{_: :b, c: p},
|
125
|
+
# front-end to search on SIOC predicate+object URIs
|
126
|
+
%w{sioc:has_creator sioc:addressed_to}.member?(p).do{|_|
|
127
|
+
{_: :form, action: '/whois',c: [{_: :input, type: :hidden, name: :p, value: p},{_: :input, name: :q}]}
|
128
|
+
},
|
129
|
+
d.map{|u,r| {c: {_: :a, href: r.url+'?set=indexPO&p=' + (URI.escape p) + '&view=page&views=timegraph,mail&v=multi&c=8', c: u}}}]}
|
130
|
+
|
131
|
+
end
|
132
|
+
|
133
|
+
|
134
|
+
class Pathname
|
135
|
+
|
136
|
+
# take N els from fs tree in sorted, depth-first order
|
137
|
+
def take count=1000, direction=:desc, offset=nil
|
138
|
+
|
139
|
+
# construct offset-path
|
140
|
+
offset = to_s + offset.gsub(/\/+/,'/').E.path if offset
|
141
|
+
|
142
|
+
# in-range indicator
|
143
|
+
ok = false
|
144
|
+
|
145
|
+
# result set
|
146
|
+
set=[]
|
147
|
+
|
148
|
+
# asc/desc operators
|
149
|
+
v,m={asc: [:id,:>=],
|
150
|
+
desc: [:reverse,:<=]}[direction]
|
151
|
+
|
152
|
+
# visitation function
|
153
|
+
visit=->nodes{
|
154
|
+
|
155
|
+
# sort nodes in asc or desc order
|
156
|
+
nodes.sort_by(&:to_s).send(v).each{|n|
|
157
|
+
ns = n.to_s
|
158
|
+
# have we got enough nodes?
|
159
|
+
return if 0 >= count
|
160
|
+
|
161
|
+
# continue if
|
162
|
+
(# already in-range
|
163
|
+
ok ||
|
164
|
+
# no offset specified
|
165
|
+
!offset ||
|
166
|
+
# offset satisfies in-range operator
|
167
|
+
(sz = [ns,offset].map(&:size).min
|
168
|
+
ns[0..sz-1].send(m,offset[0..sz-1]))) && (
|
169
|
+
if !(c = n.c).empty? # has children?
|
170
|
+
visit.(c) # visit children
|
171
|
+
else
|
172
|
+
count = count - 1 # decrement wanted-nodes count
|
173
|
+
set.push n # add node to result-set
|
174
|
+
ok = true # iterator is now within range
|
175
|
+
end )}}
|
176
|
+
|
177
|
+
visit.(c) # start
|
178
|
+
|
179
|
+
# result set
|
180
|
+
set
|
181
|
+
end
|
182
|
+
|
183
|
+
end
|
data/infod/{W → Es}/json.rb
RENAMED
@@ -1,3 +1,27 @@
|
|
1
|
+
class Hash
|
2
|
+
|
3
|
+
def graph g
|
4
|
+
g.merge!({uri=>self})
|
5
|
+
end
|
6
|
+
|
7
|
+
def mergeGraph g
|
8
|
+
g.values.each{|r|
|
9
|
+
r.triples{|s,p,o|
|
10
|
+
self[s] = {'uri' => s} unless self[s].class == Hash
|
11
|
+
self[s][p] ||= []
|
12
|
+
self[s][p].push o unless self[s][p].member? o }} if g
|
13
|
+
self
|
14
|
+
end
|
15
|
+
|
16
|
+
# tripleStream emitter
|
17
|
+
def triples
|
18
|
+
s = uri
|
19
|
+
map{|p,o|
|
20
|
+
o.class == Array ? o.each{|o| yield s,p,o} : yield(s,p,o) unless p=='uri'}
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
1
25
|
class E
|
2
26
|
|
3
27
|
def triplrJSON
|
@@ -5,7 +29,7 @@ class E
|
|
5
29
|
end
|
6
30
|
|
7
31
|
|
8
|
-
#
|
32
|
+
# tripleStream -> fs
|
9
33
|
def addJSON i,g,p=[]
|
10
34
|
fromStream({},i).map{|u,r| # stream -> graph
|
11
35
|
(E u).do{|e| # resource
|
@@ -14,13 +38,13 @@ class E
|
|
14
38
|
(p.map{|p|r[p].do{|o|e.index p,o[0]}} # index properties
|
15
39
|
j.w({u => r},true) # write doc
|
16
40
|
puts "a #{e}"
|
17
|
-
# link opaque-URI docs as siblings of base-URI
|
41
|
+
# link opaque-URI docs as siblings of base-URI for doc-discoverability
|
18
42
|
e.a('.e').do{|u| (j.ln u) unless ((j.uri == u.uri) || u.e) }
|
19
43
|
e.roonga g # index content
|
20
44
|
)}}
|
21
45
|
self
|
22
|
-
|
23
|
-
puts
|
46
|
+
rescue Exception => e
|
47
|
+
puts "addJSON #{e}"
|
24
48
|
end
|
25
49
|
|
26
50
|
fn 'view/application/json',->m,e{
|
data/infod/Es/kv.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
#watch __FILE__
|
2
|
+
class E
|
3
|
+
|
4
|
+
def []= p,o
|
5
|
+
self[p,o]
|
6
|
+
end
|
7
|
+
|
8
|
+
def [] p,o=nil, v=nil
|
9
|
+
if o # set
|
10
|
+
editFs p,o,v
|
11
|
+
else # get
|
12
|
+
(concatURI p).properties
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def editFs p, o, oO=nil
|
17
|
+
p = p.E
|
18
|
+
o = p.literal o unless o.class == E
|
19
|
+
t = (concatURI p).concatURI o
|
20
|
+
if oO # updated triple
|
21
|
+
if t.e # old triple exists?
|
22
|
+
t.deleteNode # remove triple
|
23
|
+
indexEdit p,o,'' # unindex
|
24
|
+
end
|
25
|
+
self[p,oO] unless oO.empty? # add triple
|
26
|
+
else
|
27
|
+
unless t.e # triple exists?
|
28
|
+
indexEdit p,o,nil # index triple
|
29
|
+
if o.f # add triple
|
30
|
+
# link resource
|
31
|
+
# puts "link #{o} #{t}"
|
32
|
+
o.ln t
|
33
|
+
elsif o.e
|
34
|
+
# symlink resource
|
35
|
+
# puts "symlink #{o} #{t}"
|
36
|
+
o.ln_s t
|
37
|
+
else
|
38
|
+
# name resource
|
39
|
+
puts "origin missing #{t} , adding URI ref"
|
40
|
+
t.mk
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def triplrFsStore
|
47
|
+
properties.map{|p|
|
48
|
+
self[p].map{|o|
|
49
|
+
yield uri, p.uri, o}}
|
50
|
+
end
|
51
|
+
|
52
|
+
def deletePredicate p
|
53
|
+
self[p].each{|o|self[p,o,'']}
|
54
|
+
end
|
55
|
+
|
56
|
+
def properties
|
57
|
+
subtree.map &:ro
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|