infod 0.0.3.2 → 0.0.3.3
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/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
data/infod/groonga.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#watch __FILE__
|
2
|
-
class
|
2
|
+
class R
|
3
3
|
=begin
|
4
4
|
gem install rroonga
|
5
5
|
a ruby full-text searcher & column-store
|
@@ -9,12 +9,12 @@ class E
|
|
9
9
|
fn 'view/'+Search+'Groonga',-> d,e {{_: :form, action: '/', c: [{_: :input, name: :q, style: 'font-size:2em'},{_: :input, type: :hidden, name: :graph, value: :groonga}]}}
|
10
10
|
|
11
11
|
fn 'protograph/groonga',->d,e,m{
|
12
|
-
|
12
|
+
R.groonga.do{|ga|
|
13
13
|
q = e['q'] # search expression
|
14
14
|
g = e["context"] || d.env['SERVER_NAME'] # context
|
15
15
|
|
16
16
|
begin
|
17
|
-
m['/'] = {Type =>
|
17
|
+
m['/'] = {Type => R[Search+'Groonga']} # add a groonga resource to the graph
|
18
18
|
|
19
19
|
r = (q && !q.empty?) ? ga.select{|r|(r['graph'] == g) & r["content"].match(q)} : # expression if exists
|
20
20
|
ga.select{|r| r['graph'] == g} # or just an ordered set
|
@@ -24,25 +24,25 @@ class E
|
|
24
24
|
down = r.size > start+c # prev
|
25
25
|
up = !(start<=0) # next
|
26
26
|
r = r.sort(e.has_key?('best') ? [["_score"]]:[["time","descending"]],:offset =>start,:limit =>c) # sort
|
27
|
-
r = r.map{|r|
|
27
|
+
r = r.map{|r|r['.uri'].R} # read URI
|
28
28
|
(r.map &:docs).flatten.uniq.map{|r|m[r.uri] = r.env e} # set resource thunks
|
29
29
|
|
30
|
-
m['#'] = {'uri' => '#', RDFs+'member' => r, Type=>
|
30
|
+
m['#'] = {'uri' => '#', RDFs+'member' => r, Type=>R[HTTP+'Response']} # add pagination data to request-graph
|
31
31
|
m['#'][Prev]={'uri' => '/' + {'graph' => 'groonga', 'q' => q, 'start' => start + c, 'c' => c}.qs} if down
|
32
32
|
m['#'][Next]={'uri' => '/' + {'graph' => 'groonga', 'q' => q, 'start' => start - c, 'c' => c}.qs} if up
|
33
33
|
|
34
34
|
rescue Groonga::SyntaxError => x
|
35
|
-
m['#'] = {Type =>
|
35
|
+
m['#'] = {Type => R[COGS+'Exception'], Title => "invalid expr", Content => CGI.escapeHTML(x.message)}
|
36
36
|
e['nocache']=true
|
37
37
|
end
|
38
38
|
|
39
39
|
F['docsID'][m,e]}}
|
40
40
|
|
41
|
-
def
|
41
|
+
def R.groonga
|
42
42
|
@groonga ||=
|
43
43
|
(begin require 'groonga'
|
44
|
-
|
45
|
-
Groonga["
|
44
|
+
R['/index/groonga'].groonga
|
45
|
+
Groonga["R"]
|
46
46
|
rescue LoadError => e; end)
|
47
47
|
end
|
48
48
|
|
@@ -52,7 +52,7 @@ class E
|
|
52
52
|
dirname.mk # create containing dir
|
53
53
|
Groonga::Database.create(:path => d) # create db
|
54
54
|
Groonga::Schema.define{|s| # create schema
|
55
|
-
s.create_table("
|
55
|
+
s.create_table("R",:type => :hash,:key_type => "ShortText"){|t|
|
56
56
|
t.short_text "uri"
|
57
57
|
t.short_text "graph"
|
58
58
|
t.text "content"
|
@@ -61,25 +61,25 @@ class E
|
|
61
61
|
:type => :patricia_trie,
|
62
62
|
:key_normalize => true,
|
63
63
|
:default_tokenizer => "TokenBigram"){|t|
|
64
|
-
%w{graph content}.map{|c| t.index("
|
64
|
+
%w{graph content}.map{|c| t.index("R." + c) }}}
|
65
65
|
end
|
66
66
|
|
67
67
|
# add
|
68
68
|
def roonga graph="global", m = self.graph
|
69
|
-
|
69
|
+
R.groonga.do{|g|
|
70
70
|
m.map{|u,i|
|
71
71
|
r = g[u] || g.add(u) # create or load entry
|
72
72
|
r.uri = u # update data
|
73
73
|
r.graph = graph.to_s
|
74
74
|
r.content = i.to_s
|
75
|
-
r.time = i[
|
75
|
+
r.time = i[R::Date].do{|t|t[0].to_time}
|
76
76
|
}}
|
77
77
|
self
|
78
78
|
end
|
79
79
|
|
80
80
|
# remove
|
81
81
|
def unroonga
|
82
|
-
g =
|
82
|
+
g = R.groonga
|
83
83
|
graph.keys.push(uri).map{|u|g[u].delete}
|
84
84
|
end
|
85
85
|
|
data/infod/histogram.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
#watch __FILE__
|
2
|
-
class
|
2
|
+
class R
|
3
3
|
|
4
4
|
fn 'view/histogram',->m,e{
|
5
|
-
e.q['a'].do{|a|
|
6
|
-
(
|
5
|
+
e.q['a'].do{|a|F['histogram/main'][m,e]} ||
|
6
|
+
(F['view/facetSelect'][m,e])}
|
7
7
|
|
8
8
|
fn 'histogram/main',->d,e{
|
9
9
|
|
@@ -17,10 +17,10 @@ class E
|
|
17
17
|
v = F['view/'+(e.q['hv']||'title')]
|
18
18
|
|
19
19
|
# construct histogram bins
|
20
|
-
|
20
|
+
F['histogram/bins'][d,a,n].do{|h,m|
|
21
21
|
|
22
22
|
[H.css('/css/hist'),%w{mu hist}.map{|s|H.js('/js/'+s)},
|
23
|
-
|
23
|
+
F['histogram'][h],{style: "width: 100%; height: 5em"},
|
24
24
|
h.map{|b,r|
|
25
25
|
# skip empty bins
|
26
26
|
r.empty? ? ' ' :
|
data/infod/html.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
#watch __FILE__
|
2
2
|
|
3
|
-
# (H) templates
|
4
3
|
def H _
|
5
4
|
case _
|
6
5
|
when Hash
|
@@ -21,14 +20,14 @@ class H
|
|
21
20
|
|
22
21
|
def H.js a,inline=false
|
23
22
|
p = a + '.js'
|
24
|
-
inline ? {_: :script, c: p.
|
23
|
+
inline ? {_: :script, c: p.R.r} :
|
25
24
|
{_: :script, type: "text/javascript", src: p}
|
26
25
|
end
|
27
26
|
|
28
27
|
def H.css a,inline=false
|
29
28
|
p = a + '.css'
|
30
|
-
inline ? {_: :style, c: p.
|
31
|
-
{_: :link, href: p, rel: :stylesheet, type:
|
29
|
+
inline ? {_: :style, c: p.R.r} :
|
30
|
+
{_: :link, href: p, rel: :stylesheet, type: R::MIME[:css]}
|
32
31
|
end
|
33
32
|
|
34
33
|
def H.once e,n,*h
|
@@ -39,17 +38,19 @@ class H
|
|
39
38
|
end
|
40
39
|
|
41
40
|
class Array
|
42
|
-
def
|
43
|
-
|
41
|
+
def cr; intersperse "\n" end
|
42
|
+
def head; self[0] end
|
43
|
+
def html v=nil,g=nil; map{|e|e.html v,g}.join ' ' end
|
44
|
+
def h; join.h end
|
45
|
+
def intersperse i
|
46
|
+
inject([]){|a,b|a << b << i}[0..-2]
|
44
47
|
end
|
48
|
+
def tail; self[1..-1] end
|
49
|
+
def justArray; self end
|
45
50
|
end
|
46
51
|
|
47
52
|
class Object
|
48
|
-
def html *a
|
49
|
-
name = self.class
|
50
|
-
href = "https://duckduckgo.com/?q=ruby+#{name}"
|
51
|
-
"<a href=#{href}><b>#{name}</b></a>"
|
52
|
-
end
|
53
|
+
def html *a; self.class end
|
53
54
|
end
|
54
55
|
|
55
56
|
class String
|
@@ -69,10 +70,14 @@ end
|
|
69
70
|
|
70
71
|
class Fixnum
|
71
72
|
def html e=nil,g=nil; to_s end
|
73
|
+
def max i; i > self ? self : i end
|
74
|
+
def min i; i < self ? self : i end
|
72
75
|
end
|
73
76
|
|
74
77
|
class Float
|
75
78
|
def html e=nil,g=nil; to_s end
|
79
|
+
def max i; i > self ? self : i end
|
80
|
+
def min i; i < self ? self : i end
|
76
81
|
end
|
77
82
|
|
78
83
|
class TrueClass
|
@@ -98,10 +103,10 @@ class Hash
|
|
98
103
|
H({_: :table, class: :html, c: map{|k,v|
|
99
104
|
unless k == 'uri' && (v.match IsBnode)
|
100
105
|
{_: :tr, property: k, c:
|
101
|
-
[k ==
|
106
|
+
[k == R::Content ? {_: :td, class: :val, colspan: 2, c: v} :
|
102
107
|
[
|
103
|
-
({_: :td, c: [{_: :a, name: k, href: (k == 'uri' ? v : k), c: k.to_s.abbrURI}], class: :key} if key),
|
104
|
-
{_: :td, c: k == 'uri' ? v.
|
108
|
+
({_: :td, c: [{_: :a, name: k, href: (k == 'uri' ? (v.R.docBase.localURL e)+'?graph=edit' : k), c: k.to_s.abbrURI}], class: :key} if key),
|
109
|
+
{_: :td, c: k == 'uri' ? v.R.do{|u| {_: :a, id: u, href: u.url, c: v}} : v.html(e,g), class: :val},
|
105
110
|
]]}
|
106
111
|
end
|
107
112
|
}})
|
@@ -109,34 +114,31 @@ class Hash
|
|
109
114
|
end
|
110
115
|
end
|
111
116
|
|
112
|
-
class
|
117
|
+
class R
|
113
118
|
|
114
119
|
def html *a
|
115
120
|
url.href
|
116
121
|
end
|
117
122
|
|
118
|
-
|
123
|
+
F['view']=->d,e{
|
119
124
|
d.values.select{|r|
|
120
125
|
!r.has_key?('uri') || # URI field missing
|
121
126
|
!r.uri.match(IsBnode) # blank node
|
122
127
|
true
|
123
128
|
}.
|
124
129
|
sort_by{|r| r[Date].do{|d| d[0].to_s} || ''}.reverse.
|
125
|
-
map{|r|
|
130
|
+
map{|r| F['view/select'][r,e,d]}}
|
126
131
|
|
127
|
-
|
132
|
+
F['view/base']=->d,e,k=true,graph=nil{
|
128
133
|
[H.once(e,'base',H.css('/css/html')),
|
129
134
|
d.values.map{|v|v.html e,graph,k}]}
|
130
135
|
|
131
|
-
|
136
|
+
F['view/select']=->r,e,d=nil{
|
132
137
|
graph = {r.uri => r}
|
133
138
|
view = nil
|
134
139
|
if r.class == Hash
|
135
140
|
(r[Type].class==Array ? r[Type] : [r[Type]]).do{|types|
|
136
|
-
views = types.map{|t|
|
137
|
-
# discard non-URIs
|
138
|
-
t.uri if t.respond_to? :uri}.
|
139
|
-
compact.map{|t|
|
141
|
+
views = types.map(&:maybeURI).compact.map{|t|
|
140
142
|
subtype = t
|
141
143
|
type = subtype.split(/\//)[-2]
|
142
144
|
[F['view/' + subtype],
|
@@ -150,12 +152,6 @@ class E
|
|
150
152
|
view[graph,e]
|
151
153
|
end}
|
152
154
|
|
153
|
-
# enumerate available views
|
154
|
-
fn 'view/?',->d,e{
|
155
|
-
F.keys.grep(/^view\/(?!application|text\/x-)/).map{|v|
|
156
|
-
v = v[5..-1] # eat selector
|
157
|
-
[{_: :a, href: e['REQUEST_PATH']+e.q.merge({'view'=>v}).qs, c: v},"<br>\n"]}}
|
158
|
-
|
159
155
|
def triplrBlob
|
160
156
|
glob.select(&:f).do{|f|f.map{|r|
|
161
157
|
yield r.uri,Type,E('blob')
|
@@ -165,7 +161,6 @@ class E
|
|
165
161
|
yield uri,Content,(f && read).do{|r|enc ? r.force_encoding(enc).to_utf8 : r}.hrefs
|
166
162
|
end
|
167
163
|
|
168
|
-
require 'nokogiri'
|
169
164
|
def nokogiri; Nokogiri::HTML.parse read end
|
170
165
|
|
171
166
|
F['HTMLbody'] = -> b {
|
@@ -179,6 +174,14 @@ class E
|
|
179
174
|
h.to_s
|
180
175
|
}
|
181
176
|
|
177
|
+
fn 'view/'+HTTP+'Response',->d,e{
|
178
|
+
d['#'].do{|u|
|
179
|
+
[u[Prev].do{|p|{_: :a, rel: :prev, href: p.uri, c: '←',style: 'color:#fff;background-color:#000;font-size:2.4em;float:left;clear:both'}},
|
180
|
+
u[Next].do{|n|{_: :a, rel: :next, href: n.uri, c: '→',style: 'color:#000;background-color:#fff;font-size:2.4em;float:right;clear:both;'}},
|
181
|
+
{_: :a, rel: :nofollow, href: e['REQUEST_PATH'].sub(/\.html$/,'') + e.q.merge({'view'=>'data'}).qs, # data browser
|
182
|
+
c: {_: :img, src: '/css/misc/cube.png', style: 'height:2em;background-color:white;padding:.54em;border-radius:1em;margin:.2em'}},
|
183
|
+
(H.js '/js/pager'),(H.once e,:mu,(H.js '/js/mu'))]}} # (n)ext (p)rev key binding
|
184
|
+
|
182
185
|
def contentURIresolve *f
|
183
186
|
send(*f){|s,p,o|
|
184
187
|
yield s, p, p == Content ?
|
@@ -210,11 +213,11 @@ class E
|
|
210
213
|
{_: :a, href: '#', c: '-', id: :hideP},
|
211
214
|
{_: :a, href: '#', c: '+', id: :showP},
|
212
215
|
{_: :span, id: 'properties',
|
213
|
-
c:
|
216
|
+
c: R.graphProperties(d).map{|k|
|
214
217
|
{_: :a, class: :n, href: k, c: k.label+' '}}},
|
215
218
|
{_: :style, id: :pS},
|
216
219
|
{_: :style, id: :lS}),
|
217
|
-
|
220
|
+
F['view/'+(e.q['pv']||'table')][d,e]]}
|
218
221
|
|
219
222
|
# table-cell placement on sparse matrix of rows/columns
|
220
223
|
# cal.rb contains an example usage
|
@@ -223,7 +226,7 @@ class E
|
|
223
226
|
if layout
|
224
227
|
[H.once(e,'table',H.css('/css/table')),
|
225
228
|
{_: :table, c:
|
226
|
-
{_: :tbody, c:
|
229
|
+
{_: :tbody, c: F['table/'+layout][d].do{|t|
|
227
230
|
rx = t.keys.max
|
228
231
|
rm = t.keys.min
|
229
232
|
c = t.values.map(&:keys)
|
@@ -234,15 +237,15 @@ class E
|
|
234
237
|
t[r].do{|r|
|
235
238
|
(cm..cx).map{|c|
|
236
239
|
r[c].do{|c|
|
237
|
-
{_: :td, class: :cell, c:
|
238
|
-
|
239
|
-
|
240
|
+
{_: :td, class: :cell, c:F['view/'+(a||e.q['cellview']||'title')][c,e]}} ||
|
241
|
+
{_: :td}}}}} ||
|
242
|
+
'' }}}]
|
240
243
|
else
|
241
244
|
"table= layout arg required"
|
242
245
|
end}
|
243
246
|
|
244
247
|
fn 'view/table',->g,e{
|
245
|
-
keys =
|
248
|
+
keys = R.graphProperties g
|
246
249
|
v = g.values
|
247
250
|
e.q['sort'].do{|p|
|
248
251
|
p = p.expand
|
@@ -253,6 +256,6 @@ class E
|
|
253
256
|
[H.css('/css/table'),
|
254
257
|
{_: :table,:class => :tab,
|
255
258
|
c: [{_: :tr, c: keys.map{|k|{_: :th, class: :label, property: k, c: k.abbrURI}}},
|
256
|
-
v.map{|e|{_: :tr, about: e.uri, c: keys.map{|k| {_: :td, property: k, c: k=='uri' ? e.
|
259
|
+
v.map{|e|{_: :tr, about: e.uri, c: keys.map{|k| {_: :td, property: k, c: k=='uri' ? e.R.html : e[k].html}}}}]}]}
|
257
260
|
|
258
261
|
end
|
data/infod/image.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
#watch __FILE__
|
2
|
-
class
|
2
|
+
class R
|
3
3
|
|
4
4
|
def triplrImage &f
|
5
|
-
yield uri,Type,
|
5
|
+
yield uri,Type,R[DC+'Image']
|
6
6
|
triplrStdOut 'exiftool', EXIF, &f
|
7
7
|
end
|
8
8
|
|
@@ -12,7 +12,7 @@ class E
|
|
12
12
|
size = r.q['px'].to_i.min(8).max(4096)
|
13
13
|
stat = i.node.stat
|
14
14
|
id = [stat.ino,stat.mtime,size].h.dive
|
15
|
-
path =
|
15
|
+
path = R['/cache/thumbnail/'+id+'.png']
|
16
16
|
if !path.e
|
17
17
|
path.dirname.mk
|
18
18
|
if i.mimeP.match(/^video/)
|
@@ -28,7 +28,7 @@ class E
|
|
28
28
|
|
29
29
|
fn 'view/img',->i,_{
|
30
30
|
[i.values.select{|v|v.class==Hash}.map{|i|
|
31
|
-
i[Type] && (i[Type].class==Array ? i[Type] : [i[Type]]).map
|
31
|
+
i[Type] && (i[Type].class==Array ? i[Type] : [i[Type]]).map(&:maybeURI).include?(DC+'Image') &&
|
32
32
|
[{_: :a, href: i.url, c: {_: :img, style:'float:left;max-width:61.8%', src: i.url}},
|
33
33
|
i.html]},
|
34
34
|
(H.css '/css/img')]}
|
@@ -70,9 +70,7 @@ class E
|
|
70
70
|
|
71
71
|
# check object URIs for image extension
|
72
72
|
(v.respond_to?(:values) &&
|
73
|
-
v.values.flatten.map
|
74
|
-
v.respond_to?(:uri) && v.uri
|
75
|
-
}.select(&x))
|
73
|
+
v.values.flatten.map(&:maybeURI).select(&x))
|
76
74
|
|
77
75
|
].flatten.uniq.compact.map{|s|
|
78
76
|
# view
|
@@ -85,8 +83,8 @@ class E
|
|
85
83
|
(seen[i[:uri]] = true
|
86
84
|
i[:c].())}]}
|
87
85
|
|
88
|
-
def
|
89
|
-
def
|
86
|
+
def R.c; '#%06x' % rand(16777216) end
|
87
|
+
def R.cs; '#%02x%02x%02x' % F['color/hsv2rgb'][rand*6,1,1] end
|
90
88
|
|
91
89
|
fn 'color/hsv2rgb',->h,s,v{
|
92
90
|
i = h.floor
|
data/infod/index.rb
CHANGED
@@ -1,24 +1,12 @@
|
|
1
1
|
#watch __FILE__
|
2
|
-
class
|
2
|
+
class R
|
3
3
|
|
4
4
|
# POSIX-fs based index of triples
|
5
5
|
#
|
6
6
|
|
7
|
-
# index a triple
|
8
7
|
def index p,o
|
9
|
-
|
10
|
-
|
11
|
-
end
|
12
|
-
|
13
|
-
# index a triple - no type-normalization
|
14
|
-
# we jsut rotate them, use existing k/v store and set @noIndex to stop looping infinitely to index the index..
|
15
|
-
def indexEdit p,o,a
|
16
|
-
return if @noIndex
|
17
|
-
p.pIndex.noIndex[o,self,a]
|
18
|
-
end
|
19
|
-
def noIndex
|
20
|
-
@noIndex = 1
|
21
|
-
self
|
8
|
+
return unless o.class == R
|
9
|
+
p.R.indexPath.setFs o,self,false,false
|
22
10
|
end
|
23
11
|
|
24
12
|
# reachable graph along named predicate
|
@@ -28,10 +16,10 @@ class E
|
|
28
16
|
v[uri] = true # visited mark
|
29
17
|
|
30
18
|
rel = g[uri].do{|s|s[p]} ||[]
|
31
|
-
rev = (p.
|
19
|
+
rev = (p.R.po self) ||[]
|
32
20
|
|
33
21
|
rel.concat(rev).map{|r|
|
34
|
-
v[r.uri] || (r.
|
22
|
+
v[r.uri] || (r.R.walk p,g,v)}
|
35
23
|
|
36
24
|
g
|
37
25
|
end
|
@@ -40,51 +28,34 @@ class E
|
|
40
28
|
global = !r.has_key?('local')
|
41
29
|
p = global ? d.pathSegment : d
|
42
30
|
loc = global ? '' : '&local'
|
43
|
-
c = ((r['c'].do{|c|c.to_i} || 12) + 1).max(
|
31
|
+
c = ((r['c'].do{|c|c.to_i} || 12) + 1).max(1024) # an extra for next-page pointer
|
44
32
|
o = r['d'] =~ /^a/ ? :asc : :desc # direction
|
45
|
-
(p.take c, o, r['offset'].do{|o|o.
|
33
|
+
(p.take c, o, r['offset'].do{|o|o.R}).do{|s| # take subtree
|
46
34
|
first, last = s[0], s.size > 1 && s.pop
|
47
35
|
desc, asc = o == :asc ? [first,last] : [last,first]
|
48
36
|
u = m['#']
|
49
|
-
u[Type] =
|
37
|
+
u[Type] = R[HTTP+'Response']
|
50
38
|
u[Prev] = {'uri' => d.uri + "?set=depth&c=#{c-1}&d=desc#{loc}&offset=" + (URI.escape desc.uri)} if desc
|
51
39
|
u[Next] = {'uri' => d.uri + "?set=depth&c=#{c-1}&d=asc#{loc}&offset=" + (URI.escape asc.uri)} if asc
|
52
40
|
s }}
|
53
41
|
|
54
|
-
def pIndex
|
55
|
-
shorten.prependURI '/index/'
|
56
|
-
end
|
57
|
-
|
58
|
-
def poIndex o
|
59
|
-
pIndex.concatURI o
|
60
|
-
end
|
61
|
-
|
62
|
-
# predicate+object pair lookup
|
63
42
|
def po o
|
64
|
-
|
43
|
+
indexPath.predicate o, false
|
65
44
|
end
|
66
45
|
|
67
|
-
def
|
68
|
-
|
69
|
-
end
|
70
|
-
|
71
|
-
def rangePO n=8,d=:desc,s=nil,o
|
72
|
-
poIndex(o).subtree(n,d,s).map &:ro
|
73
|
-
end
|
74
|
-
|
75
|
-
def subtree *a
|
76
|
-
u.take *a
|
46
|
+
def indexPath
|
47
|
+
shorten.prependURI '/index/'
|
77
48
|
end
|
78
49
|
|
79
50
|
def take *a
|
80
|
-
|
51
|
+
node.take(*a).map &:R
|
81
52
|
end
|
82
53
|
|
83
54
|
def randomLeaf
|
84
55
|
c.empty? && self || c.r.randomLeaf
|
85
56
|
end
|
86
57
|
|
87
|
-
def
|
58
|
+
def R.graphProperties g
|
88
59
|
g.values.select{|v|v.respond_to? :keys}.map(&:keys).flatten.uniq
|
89
60
|
end
|
90
61
|
|
@@ -108,7 +79,6 @@ class Pathname
|
|
108
79
|
nodes.sort_by(&:to_s).send(v).each{|n|
|
109
80
|
ns = n.to_s
|
110
81
|
return if 0 >= count
|
111
|
-
|
112
82
|
(ok || # already in-range
|
113
83
|
!offset || # no offset required
|
114
84
|
(sz = [ns,offset].map(&:size).min
|