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
@@ -1,86 +0,0 @@
|
|
1
|
-
#watch __FILE__
|
2
|
-
class E
|
3
|
-
|
4
|
-
F["?"]||={}
|
5
|
-
F["?"].update({'taft'=>{
|
6
|
-
'graph'=>'|',
|
7
|
-
'|'=>'triplrMozHist',
|
8
|
-
'view'=>'page',
|
9
|
-
'v'=>'timegraph',
|
10
|
-
'arc'=>'referer'}})
|
11
|
-
|
12
|
-
# massage data for timegraph
|
13
|
-
fn 'filter/timegraph',->e,m,_{
|
14
|
-
|
15
|
-
e['timegraph'] ||= true
|
16
|
-
|
17
|
-
x = e['x'] || Date # x prop
|
18
|
-
y = e['y'] # y property
|
19
|
-
|
20
|
-
# 2D values
|
21
|
-
vX = m.map{|_,r|r[x]}.flatten.compact.map(&:to_time).map &:to_f
|
22
|
-
vY = m.map{|_,r|r[y]}.flatten.compact.map &:to_f
|
23
|
-
maxX = vX.max
|
24
|
-
minX = vX.min
|
25
|
-
maxY = vY.max
|
26
|
-
minY = vY.min
|
27
|
-
|
28
|
-
# scaling-ratio to normalize values to %
|
29
|
-
scaleX = 100/((maxX-minX).do{|v|v==0 ? 100 : v}||100)
|
30
|
-
scaleY = 100/((maxY-minY).do{|v|v==0 ? 100 : v}||100)
|
31
|
-
|
32
|
-
# annotate resources with positioning data
|
33
|
-
m.map{|u,r|
|
34
|
-
r['x'] = [*r[x]][0].do{|v|(maxX - v.to_time.to_f)*scaleX} || 0
|
35
|
-
r['y'] = y.do{|y|[*r[y]][0].do{|v|(maxY - v.to_f)*scaleY} || 0} || rand(100)}
|
36
|
-
}
|
37
|
-
|
38
|
-
# a linked-timeline view
|
39
|
-
fn 'view/timegraph',->d,e{
|
40
|
-
# use standard structure for examine faceted-filtering
|
41
|
-
i=F['view/timegraph/item']
|
42
|
-
Fn 'view/timegraph/base',d,e,->{d.map{|u,r|i.(r,e)}}}
|
43
|
-
|
44
|
-
# timegraph container-element
|
45
|
-
fn 'view/timegraph/base',->d,e,c{
|
46
|
-
Fn 'filter/timegraph', e.q, d, nil unless e.q['timegraph']==true
|
47
|
-
|
48
|
-
e[:graph] = d
|
49
|
-
e[:group] = {}
|
50
|
-
e[:color] = E.c
|
51
|
-
|
52
|
-
[H.css('/css/timegraph'),{class: :timegraph, c: c.()}]}
|
53
|
-
|
54
|
-
# timegraph entry
|
55
|
-
fn 'view/timegraph/item',->r,x{
|
56
|
-
# skip resources w/o x-axis field
|
57
|
-
if r[x.q['x'] || Date]
|
58
|
-
|
59
|
-
labelP = x.q['label'].expand || Creator
|
60
|
-
label = (r[labelP][0]).do{|l|
|
61
|
-
l.respond_to?(:uri) ? l.uri : l.to_s}
|
62
|
-
lc = x[:group][label] ||= E.c
|
63
|
-
|
64
|
-
[{style: "top: #{r['x']}%; left: 0", class: :date, c: r[Date][0]},
|
65
|
-
{style: "top: #{r['x']}%; left: #{r['y']}%",
|
66
|
-
c: [{_: :a, href: r.url, c: '#', class: :link},
|
67
|
-
{_: :a,
|
68
|
-
title: r[Date][0],
|
69
|
-
href: '#'+r.uri,
|
70
|
-
class: :label,
|
71
|
-
style: "background-color: #{lc}",
|
72
|
-
c: label,
|
73
|
-
}]},
|
74
|
-
|
75
|
-
# arc(s)
|
76
|
-
{_: :svg, c:
|
77
|
-
r[x.q['arc'].expand].map{|e|
|
78
|
-
# target resource
|
79
|
-
x[:graph][e.uri].do{|e|
|
80
|
-
# arc path
|
81
|
-
{_: :line, class: :arc, stroke: x[:color], 'stroke-dasharray'=>"2,2",
|
82
|
-
y1: e['x'].to_s+'%', x1: e['y'].to_s+'%',
|
83
|
-
y2: r['x'].to_s+'%', x2: r['y'].to_s+'%'}}}}]
|
84
|
-
end }
|
85
|
-
|
86
|
-
end
|
@@ -1,24 +0,0 @@
|
|
1
|
-
class E
|
2
|
-
|
3
|
-
## SIMILE Timeline
|
4
|
-
# http://www.simile-widgets.org/
|
5
|
-
|
6
|
-
# JSON format
|
7
|
-
fn Render+'application/timeline',->d,e{
|
8
|
-
{dateTimeFormat: 'iso8601',
|
9
|
-
events: d.values.map{|r|
|
10
|
-
r[Date].do{|d|
|
11
|
-
{description: r.uri,
|
12
|
-
title: r[Title],
|
13
|
-
start: [*d][0],
|
14
|
-
link: r.url,
|
15
|
-
}}}.compact}.to_json}
|
16
|
-
|
17
|
-
fn 'head/timeline',->d,e{
|
18
|
-
['<script>var t="'+e['REQUEST_PATH']+e.q.except('view','?').merge({format: 'application/timeline'}).qs+'"</script>',
|
19
|
-
(H.js '/js/timeline'),
|
20
|
-
(H.js 'http://api.simile-widgets.org/timeline/2.3.1/timeline-api')]}
|
21
|
-
|
22
|
-
fn 'view/timeline',->d,e{'<div id="tl" class="timeline-default" style="height: 300px;"></div>'}
|
23
|
-
|
24
|
-
end
|
data/infod/W/find.rb
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
#watch __FILE__
|
2
|
-
class E
|
3
|
-
|
4
|
-
fn 'set/find',->e,q,m{
|
5
|
-
t=q['day'] && q['day'].match(/^\d+$/) && '-ctime -'+q['day']
|
6
|
-
s=q['size'] && q['size'].match(/^\d+$/) && '-size +'+q['size']+'M'
|
7
|
-
r=q['q'] && '-iregex ' + ('.*'+q['q']+'.*').sh
|
8
|
-
`find #{e.sh} #{t} #{s} #{r} | head -n 1024`.lines.map &:pathToURI}
|
9
|
-
|
10
|
-
fn 'graph/find',->e,q,m{
|
11
|
-
(Fn 'set/find', e,q,m).do{|f|
|
12
|
-
if f.size < 256
|
13
|
-
f.map{|r|r.fromStream m,:triplrInode,false}
|
14
|
-
else
|
15
|
-
f.map{|r|m[r.uri]=r}
|
16
|
-
end}}
|
17
|
-
|
18
|
-
fn 'view/find',->i,e{
|
19
|
-
{_: :form, method: :GET, action: e['REQUEST_PATH'].t, style: 'float: right',
|
20
|
-
c: [{_: :input, name: :graph, value: :find, type: :hidden},
|
21
|
-
{_: :input, name: :view, value: :ls, type: :hidden},
|
22
|
-
{_: :input, name: :q}]}}
|
23
|
-
|
24
|
-
end
|
data/infod/W/grep.rb
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
#watch __FILE__
|
2
|
-
class E
|
3
|
-
|
4
|
-
fn 'set/grep',->e,q,m{
|
5
|
-
`grep -rl#{q.has_key?('i') && 'i'} #{q['q'].sh} #{e.sh}`.lines.map &:pathToURI
|
6
|
-
}
|
7
|
-
|
8
|
-
fn 'view/grep',->d,e{
|
9
|
-
w=e.q['q'].scan(/[\w]+/).map(&:downcase).uniq # split/dedupe words
|
10
|
-
c={}; w.each_with_index{|w,i|c[w]=i} # word index
|
11
|
-
a=/(#{w.join '|'})/i # OR pattern
|
12
|
-
p=/#{w.join '.*'}/i # sequential pattern
|
13
|
-
[H.css('/css/search'),{_: :style, c: c.values.map{|i| # word styles
|
14
|
-
b = rand(16777216) # random color
|
15
|
-
f = b > 8388608 ? :black : :white # keep text contrasty
|
16
|
-
".w#{i} {background-color: #{'#%06x' % b}; color: #{f}}\n"}},# CSS
|
17
|
-
d.map{|u,r| l = r.to_s.gsub(/<[^>]*>/,'').lines # plaintextify
|
18
|
-
g = l.grep p # sequential match first
|
19
|
-
g = l.grep a if g.empty? # OR match second
|
20
|
-
!g.empty? && # find anything?
|
21
|
-
[r.E.do{|e|{_: :a,href: e.url,c: e}},'<br>', # doc link
|
22
|
-
[g[-1*(g.size.max 3)..-1].map{|l| # show 3 matches per doc
|
23
|
-
l[0..404].gsub(a){|g| # create exerpt
|
24
|
-
H({_: :span, class: "w w#{c[g.downcase]}",c: g})} # style exerpt
|
25
|
-
},"<br>"]]}]}
|
26
|
-
|
27
|
-
end
|
data/infod/W/html.rb
DELETED
@@ -1,143 +0,0 @@
|
|
1
|
-
#watch __FILE__
|
2
|
-
|
3
|
-
class Array
|
4
|
-
def html table=true
|
5
|
-
map(&:html).join ' '
|
6
|
-
end
|
7
|
-
end
|
8
|
-
|
9
|
-
class Object
|
10
|
-
def html *a
|
11
|
-
to_s.gsub('<','<').gsub('>','>')
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
class String
|
16
|
-
def br
|
17
|
-
gsub(/\n/,"<br>\n")
|
18
|
-
end
|
19
|
-
def href name=nil
|
20
|
-
'<a href="'+self+'">'+(name||(Fn 'abbrURI',self))+'</a>'
|
21
|
-
end
|
22
|
-
def html
|
23
|
-
if match /\A(https?:\/\/)[\S]+\Z/
|
24
|
-
href
|
25
|
-
else
|
26
|
-
self
|
27
|
-
end
|
28
|
-
rescue
|
29
|
-
self
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
class Hash
|
34
|
-
def html
|
35
|
-
H({_: :table, class: :html, c:
|
36
|
-
map{|k,v|
|
37
|
-
{_: :tr, property: k, c:
|
38
|
-
[{_: :td,c: (Fn 'abbrURI',k), class: :key},
|
39
|
-
{_: :td,
|
40
|
-
c: (case k
|
41
|
-
when E::Content
|
42
|
-
{_: :pre, style: "white-space: pre-wrap", c: v}
|
43
|
-
when 'uri'
|
44
|
-
u = v.E
|
45
|
-
{_: :a, id: u, href: u.url, c: v}
|
46
|
-
else
|
47
|
-
v.html
|
48
|
-
end), class: :val}].cr}}.cr})
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
class E
|
53
|
-
def html name=nil,l=false
|
54
|
-
(l ? url : uri).href name
|
55
|
-
end
|
56
|
-
|
57
|
-
def link
|
58
|
-
html '#',true
|
59
|
-
end
|
60
|
-
|
61
|
-
fn 'abbrURI',->u{
|
62
|
-
u.to_s.sub(/(?<scheme>[a-z]+:\/\/)?(?<abbr>.*?)(?<frag>[^#\/]+)$/,
|
63
|
-
'<span class="abbr"><span class="scheme">\k<scheme></span>\k<abbr></span><span class="frag">\k<frag></span>')
|
64
|
-
}
|
65
|
-
|
66
|
-
fn 'head',->d,e{
|
67
|
-
[{_: :title, c: d.attr(Title) || e.uri},
|
68
|
-
(Fn 'head.formats',e),
|
69
|
-
(Fn 'head.icon')].cr}
|
70
|
-
|
71
|
-
fn 'head.formats',->e{
|
72
|
-
F.keys.grep(/^render/).map{|f|
|
73
|
-
f = f[7..-1]
|
74
|
-
{_: :link, rel: :meta, type: f, href:'http://' + e['SERVER_NAME'] + e['REQUEST_PATH'] + e.q.merge({'format' => f}).qs}}.cr}
|
75
|
-
|
76
|
-
fn 'head.icon',->{{_: :link, href:'/css/i/favicon.ico', rel: :icon}}
|
77
|
-
|
78
|
-
# domain-specific view
|
79
|
-
fn 'view',->d,e{( Fn 'view/divine/set',d,e)||
|
80
|
-
d.values.map{|r|Fn 'view/divine/item',r,e}}
|
81
|
-
|
82
|
-
# no domain-specific view
|
83
|
-
fn 'view/base',->d,e{[H.css('/css/html'),d.values.map(&:html)]}
|
84
|
-
|
85
|
-
# select view - filesystem hints
|
86
|
-
fn 'view/divine/set',->d,e{
|
87
|
-
d.values.map{|e|e.E.base}.do{|b|
|
88
|
-
s = b.size.to_f
|
89
|
-
t = 0.42 # threshold
|
90
|
-
if b.grep(/^msg\./).size / s > t # email
|
91
|
-
Fn 'view/threads',d,e
|
92
|
-
elsif b.grep(/(aif|wav|flac|mp3|m4a|aac|ogg)$/i).size / s > t # audio
|
93
|
-
Fn 'view/audioplayer', d,e
|
94
|
-
elsif b.grep(/(gif|jpe?g|png)$/i).size / s > t # images
|
95
|
-
Fn 'view/th', d,e
|
96
|
-
elsif b.grep(/\.log$/).size / s > t
|
97
|
-
Fn 'view/chat', d,e
|
98
|
-
else false
|
99
|
-
end}}
|
100
|
-
|
101
|
-
Data['view/divine/item'] = "use RDF typeclass hints to choose view for a resource"
|
102
|
-
fn 'view/divine/item',->r,e{
|
103
|
-
r.class==Hash && r[Type] && r[Type][0] && r[Type][0].respond_to?(:uri) &&
|
104
|
-
(t = r[Type][0].uri; !t.empty? && # a RDF type
|
105
|
-
(F['view/'+t] ||
|
106
|
-
F['view/'+t.split(/\//)[-2]]).do{|f|
|
107
|
-
f.({r.uri => r},e)}) ||
|
108
|
-
[r.html,H.once(e,'css',H.css('/css/html'))] }
|
109
|
-
|
110
|
-
Data['view/select'] = "show a menu of all views available"
|
111
|
-
fn 'view/select',->d,e{
|
112
|
-
[{_: :style, c: 'a {min-width:22em;text-align:right}'},
|
113
|
-
F.keys.grep(/^view\/(?!application)/).map{|v|
|
114
|
-
[{_: :a, href: e['REQUEST_PATH']+e.q.merge({'view' => v[5..-1]}).qs,c: v},'<br>']}]}
|
115
|
-
F['view/?'] = F['view/select']
|
116
|
-
|
117
|
-
F['doc/view/multi'] = "display multiple comma-separated <b>views</b>"
|
118
|
-
fn 'view/multi',->d,e{e.q['views'].split(',').map{|v|Fn'view/'+v,d,e}}
|
119
|
-
|
120
|
-
def triplrBlob
|
121
|
-
glob.select(&:f).do{|f|f.map{|r|
|
122
|
-
yield r.uri,Type,E('blob')
|
123
|
-
yield r.uri,Content,r.r}} end
|
124
|
-
graphFromStream :triplrBlob
|
125
|
-
|
126
|
-
def triplrHref e=nil
|
127
|
-
yield uri,Content,read.do{|r|e ? r.force_encoding(e).to_utf8 : r}.hrefs
|
128
|
-
end
|
129
|
-
|
130
|
-
fn Render+'text/html',->d,e{
|
131
|
-
v = e.q['view'].to_s
|
132
|
-
h = F['head/'+v] || F['head']
|
133
|
-
v = F['view/'+v] || F['view']
|
134
|
-
|
135
|
-
H(e.q.has_key?('un') ? v.(d,e) :
|
136
|
-
['<!DOCTYPE html>',
|
137
|
-
{_: :html,
|
138
|
-
c: [{_: :head,
|
139
|
-
c: ['<meta charset="utf-8" />',
|
140
|
-
h.(d,e)]},
|
141
|
-
{_: :body, c: v.(d,e)}].cr}].cr)}
|
142
|
-
|
143
|
-
end
|
data/infod/W/image.rb
DELETED
@@ -1,61 +0,0 @@
|
|
1
|
-
#watch __FILE__
|
2
|
-
class E
|
3
|
-
|
4
|
-
def thumb?
|
5
|
-
mime.match(/^(image|video)/) && # is file an image?
|
6
|
-
@r.qs.match(/^[0-9]{0,3}x[0-9]{0,3}$/) && # valid dimensions?
|
7
|
-
base.match(/^[^.]/) # skip "invisible" images
|
8
|
-
end
|
9
|
-
|
10
|
-
def thumb
|
11
|
-
E['/E/images/'+
|
12
|
-
[no.stat.do{|s|
|
13
|
-
[s.ino,s.mtime]},
|
14
|
-
@r.qs].h.dive+'.png'].do{|n| n.e ||
|
15
|
-
(n.dirname.dir
|
16
|
-
mime.match(/^video/) &&
|
17
|
-
`ffmpegthumbnailer -s #{@r.qs.match(/[0-9]+/).to_s} -i #{sh} -o #{n.sh}` ||
|
18
|
-
`gm convert #{sh} -thumbnail "#{@r.qs}" #{n.sh}`)
|
19
|
-
n.env @r }
|
20
|
-
end
|
21
|
-
|
22
|
-
fn 'view/img',->i,_{
|
23
|
-
[i.values.map{|i|
|
24
|
-
[{_: :a, href: i.url,
|
25
|
-
c: {_: :img,
|
26
|
-
style:'float:left;max-width:61.8%',
|
27
|
-
src: i.url}},
|
28
|
-
i.html]},
|
29
|
-
(H.css '/css/img')
|
30
|
-
]}
|
31
|
-
|
32
|
-
fn 'view/th',->i,e{
|
33
|
-
s=e.q['s']||'233'
|
34
|
-
i.map{|u,i| u.match(/(gif|jpg|png|tiff)$/i) &&
|
35
|
-
{_: :a, href: i.url+'?view=img',
|
36
|
-
c: {_: :img, src: i.url+'?'+s+'x'+s}}}}
|
37
|
-
|
38
|
-
F['view/'+MIMEtype+'image/gif'] = F['view/th']
|
39
|
-
F['view/'+MIMEtype+'image/jpeg']= F['view/th']
|
40
|
-
F['view/'+MIMEtype+'image/png'] = F['view/th']
|
41
|
-
|
42
|
-
fn 'view/imgs',->m,e{ require 'nokogiri'
|
43
|
-
h=e.q['h'].do{|h|h.match(/^[0-9]+$/).do{|_|'height:'+h+'px'}}
|
44
|
-
seen={}
|
45
|
-
x=->i{i&&i.match(/(jpg|gif|png)$/i)&&i}
|
46
|
-
[(H.once e,:mu,H.js('/js/mu')),H.js('/js/images'),
|
47
|
-
m.values.map{|v|
|
48
|
-
[[*v[Content]].map{|c|
|
49
|
-
c.class == String &&
|
50
|
-
(Nokogiri::HTML.parse(c).do{|c|
|
51
|
-
[c.css('img').map{|i|i['src']}.compact,
|
52
|
-
c.css( 'a').map{|i|i['href']}.select(&x)]
|
53
|
-
})},
|
54
|
-
x.(v.uri),
|
55
|
-
(v.respond_to?(:values)&&v.values.flatten.map{|v|v.respond_to?(:uri)&&v.uri}.select(&x))
|
56
|
-
].flatten.uniq.compact.map{|s|
|
57
|
-
{s: s,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|
|
58
|
-
!seen[i[:s]] && (seen[i[:s]]=true; i[:c].())
|
59
|
-
}]}
|
60
|
-
|
61
|
-
end
|
data/infod/W/kv.rb
DELETED
@@ -1,66 +0,0 @@
|
|
1
|
-
class E
|
2
|
-
|
3
|
-
# a simple key/value RDF store on a fs
|
4
|
-
|
5
|
-
# *get*
|
6
|
-
# (E'http://www.kanzaki.com/ns/music#EnglishHorn')[RDFs+'comment']
|
7
|
-
# -> ["A double-reed woodwind instrument, larger member of the oboe family."]
|
8
|
-
#
|
9
|
-
# *set*
|
10
|
-
# (E'lement')['level']='trace'
|
11
|
-
#
|
12
|
-
# *update*
|
13
|
-
# (E'lement')['level','trace','abundant']
|
14
|
-
#
|
15
|
-
def [] p,o=nil, v=nil
|
16
|
-
unless o
|
17
|
-
(s p).listPredicates
|
18
|
-
else
|
19
|
-
edit E(p),(o.class == E ? o : E(p).literal(o)),v
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def []= p,o
|
24
|
-
self[p,o]
|
25
|
-
end
|
26
|
-
|
27
|
-
def edit p,o,v=nil
|
28
|
-
d=(s p).s o # object
|
29
|
-
if v # edit
|
30
|
-
if d.e
|
31
|
-
d.deleteNode # remove
|
32
|
-
indexEdit p,o,'' # unindex
|
33
|
-
end
|
34
|
-
self[p,v] unless v.empty? # add
|
35
|
-
else
|
36
|
-
unless d.e
|
37
|
-
indexEdit p,o,nil # index add
|
38
|
-
d.dir # create
|
39
|
-
end
|
40
|
-
end
|
41
|
-
touch if e
|
42
|
-
end
|
43
|
-
|
44
|
-
def triplrFsStore
|
45
|
-
listPredicates.map{|p|
|
46
|
-
self[p].map{|o|
|
47
|
-
yield uri, p.uri, o }}
|
48
|
-
end
|
49
|
-
|
50
|
-
def deletePredicate p
|
51
|
-
self[p].each{|o| self[p,o,'']}
|
52
|
-
end
|
53
|
-
|
54
|
-
# property list
|
55
|
-
# E -> [E]
|
56
|
-
def listPredicates
|
57
|
-
s = u.to_s.size+1
|
58
|
-
subtree.map{|n|n.uri[s..-1].unpath}
|
59
|
-
end
|
60
|
-
|
61
|
-
def literalBlob o
|
62
|
-
u = literalBlobURI o
|
63
|
-
u.w o,!o.class==String unless u.f
|
64
|
-
end
|
65
|
-
|
66
|
-
end
|
data/infod/W/ls.rb
DELETED
@@ -1,50 +0,0 @@
|
|
1
|
-
#watch __FILE__
|
2
|
-
class E
|
3
|
-
|
4
|
-
fn 'set/ls',->d,e,m{d.c}
|
5
|
-
|
6
|
-
# filesystem metadata only
|
7
|
-
fn 'graph/ls',->d,e,m{d.c.map{|c|c.fromStream m, :triplrInode, false}}
|
8
|
-
|
9
|
-
# basic directory view
|
10
|
-
fn 'view/dir',->i,e{
|
11
|
-
|
12
|
-
# localize URL
|
13
|
-
h = 'http://' + e['SERVER_NAME'] + '/'
|
14
|
-
l = -> u {
|
15
|
-
if u.index(h) == 0
|
16
|
-
u # already a local link
|
17
|
-
else
|
18
|
-
# generate local link
|
19
|
-
Prefix + u
|
20
|
-
end}
|
21
|
-
|
22
|
-
# item thumbnail / link
|
23
|
-
a = -> i { e = i.E
|
24
|
-
{_: :a, href: l[e.uri],
|
25
|
-
c: e.uri.match(/(gif|jpe?g|png)$/i) ? {_: :img, src: i.uri+'?233x233'} :
|
26
|
-
e.uri.sub(/.*\//,'')
|
27
|
-
}}
|
28
|
-
|
29
|
-
[(H.once e, 'dir', (H.css '/css/ls')),
|
30
|
-
i.map{|u,r| r[Posix+'dir#child'] ? # directory?
|
31
|
-
{class: :dir, style: "background-color: #{E.c}", # dir wrapper
|
32
|
-
c: [{c: [{_: :a, href: l[r.uri]+'?graph=ls&view=ls', c: r.uri.sub( 'http://'+e['SERVER_NAME'],'')}, # link to ls
|
33
|
-
{_: :a, href: l[r.uri].t, c: '/'}]},
|
34
|
-
r[Posix+'dir#child'].map{|c|a[c]}]} : # children
|
35
|
-
a[r]}]} # item
|
36
|
-
|
37
|
-
F['view/'+MIMEtype+'inode/directory']=F['view/dir']
|
38
|
-
|
39
|
-
# tabular rendering
|
40
|
-
fn 'view/ls',->i,e{
|
41
|
-
[(H.css '/css/ls'),
|
42
|
-
{_: :a, class: :up, href: E(e['uri']).parent.url+'?graph=ls&view=ls', c: '↑'},
|
43
|
-
{class: :ls,
|
44
|
-
c: (Fn 'view/tab',i,e)},
|
45
|
-
{_: :a, class: :du, href: e['REQUEST_PATH'].t+'??=du', c: :du, rel: :nofollow},
|
46
|
-
(Fn 'view/find',i,e),'<br clear=all>',
|
47
|
-
{_: :a, class: :down, href: e['uri'].E.url.t, c: '↓'},
|
48
|
-
]}
|
49
|
-
|
50
|
-
end
|