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.
@@ -1,5 +1,5 @@
1
1
  #watch __FILE__
2
- class E
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
- E.groonga.do{|ga|
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 => E[Search+'Groonga']} # add a groonga resource to the graph
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| r['.uri'].E } # URI
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=>E[HTTP+'Response']} # add pagination data to request-graph
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 => E[COGS+'Exception'], Title => "invalid expr", Content => CGI.escapeHTML(x.message)}
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 E.groonga
41
+ def R.groonga
42
42
  @groonga ||=
43
43
  (begin require 'groonga'
44
- E['/E/groonga'].groonga
45
- Groonga["E"]
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("E",:type => :hash,:key_type => "ShortText"){|t|
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("E." + c) }}}
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
- E.groonga.do{|g|
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[E::Date].do{|t|t[0].to_time}
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 = E.groonga
82
+ g = R.groonga
83
83
  graph.keys.push(uri).map{|u|g[u].delete}
84
84
  end
85
85
 
@@ -1,9 +1,9 @@
1
1
  #watch __FILE__
2
- class E
2
+ class R
3
3
 
4
4
  fn 'view/histogram',->m,e{
5
- e.q['a'].do{|a|Fn 'histogram/main',m,e} ||
6
- (Fn 'view/facetSelect',m,e)}
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
- (Fn 'histogram/bins',d,a,n).do{|h,m|
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
- (Fn 'histogram',h),{style: "width: 100%; height: 5em"},
23
+ F['histogram'][h],{style: "width: 100%; height: 5em"},
24
24
  h.map{|b,r|
25
25
  # skip empty bins
26
26
  r.empty? ? ' ' :
@@ -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.E.r} :
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.E.r} :
31
- {_: :link, href: p, rel: :stylesheet, type: E::MIME[:css]}
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 html v=nil,g=nil
43
- map{|e|e.html v,g}.join ' '
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 == E::Content ? {_: :td, class: :val, colspan: 2, c: v} :
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.E.do{|u| {_: :a, id: u, href: u.url, c: v}} : v.html(e,g), class: :val},
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 E
117
+ class R
113
118
 
114
119
  def html *a
115
120
  url.href
116
121
  end
117
122
 
118
- fn 'view',->d,e{
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| Fn 'view/select',r,e,d}}
130
+ map{|r| F['view/select'][r,e,d]}}
126
131
 
127
- fn 'view/base',->d,e,k=true,graph=nil{
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
- fn 'view/select',->r,e,d{
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: '&larr;',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: '&rarr;',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: E.graphProperties(d).map{|k|
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
- (Fn 'view/'+(e.q['pv']||'table'),d,e)]}
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: (Fn 'table/'+layout,d).do{|t|
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:(Fn 'view/'+(a||e.q['cellview']||'title'),c,e)}
238
- }||{_: :td}}}}} || ''
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 = E.graphProperties g
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.E.html : e[k].html}}}}]}]}
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
@@ -1,8 +1,8 @@
1
1
  #watch __FILE__
2
- class E
2
+ class R
3
3
 
4
4
  def triplrImage &f
5
- yield uri,Type,E[DC+'Image']
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 = E['/E/image/'+id+'.png']
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{|t|t.respond_to?(:uri) && t.uri}.include?(DC+'Image') &&
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{|v|
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 E.c; '#%06x' % rand(16777216) end
89
- def E.cs; '#%02x%02x%02x' % F['color/hsv2rgb'][rand*6,1,1] end
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
@@ -1,24 +1,12 @@
1
1
  #watch __FILE__
2
- class E
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
- p = p.E
10
- indexEdit p, (o.class == E ? o : p.literal(o)), nil
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.E.po self) ||[]
19
+ rev = (p.R.po self) ||[]
32
20
 
33
21
  rel.concat(rev).map{|r|
34
- v[r.uri] || (r.E.walk p,g,v)}
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(128) # an extra for next-page pointer
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.E}).do{|s| # take subtree
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] = E[HTTP+'Response']
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
- pIndex[o.class == E ? o : literal(o)]
43
+ indexPath.predicate o, false
65
44
  end
66
45
 
67
- def rangeP size=8, dir=:desc, offset=nil, object=nil
68
- pIndex.subtree(size,dir,offset).map &:ro
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
- no.take(*a).map &:E
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 E.graphProperties g
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