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/ls.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
#watch __FILE__
|
2
|
+
class E
|
3
|
+
|
4
|
+
fn 'view/dir',->i,e{
|
5
|
+
|
6
|
+
# item link + preview
|
7
|
+
a = -> i { i = i.E
|
8
|
+
{_: :a, href: i.localURL(e),
|
9
|
+
c: i.uri.match(/(gif|jpe?g|png)$/i) ? {_: :img, src: i.uri+'?y=scaleImage&px=233'} : i.uri.sub(/.*\//,'')}}
|
10
|
+
|
11
|
+
[(H.once e, 'dir', (H.css '/css/ls')),
|
12
|
+
i.map{|u,r|
|
13
|
+
if r[Posix+'dir#child']
|
14
|
+
url = r.E.localURL e
|
15
|
+
{class: :dir, style: "background-color: #{E.cs}", # dir wrapper
|
16
|
+
c: [{c: [{_: :a, href: url.t+'?view=ls&triplr=id', # link to "ls"
|
17
|
+
c: r.uri.sub( 'http://'+e['SERVER_NAME'],'')},
|
18
|
+
{_: :a, href: url.t, c: '/'}]},
|
19
|
+
r[Posix+'dir#child'].map{|c|a[c]}]}
|
20
|
+
else
|
21
|
+
a[r]
|
22
|
+
end
|
23
|
+
}]}
|
24
|
+
|
25
|
+
F['view/'+MIMEtype+'inode/directory'] = F['view/dir']
|
26
|
+
|
27
|
+
fn 'view/ls',->i,e{
|
28
|
+
dir = e['uri'].E
|
29
|
+
path = dir.pathSegment
|
30
|
+
up = (if !path || path.uri == '/'
|
31
|
+
'/'
|
32
|
+
else
|
33
|
+
dir.parent.url.t+'?view=ls&triplr=id'
|
34
|
+
end)
|
35
|
+
|
36
|
+
[(H.css '/css/ls'),
|
37
|
+
{_: :a, class: :up, href: up, c: '↑'},
|
38
|
+
{class: :ls,
|
39
|
+
c: (Fn 'view/table',i,e)},
|
40
|
+
(Fn 'view/find',i,e),'<br clear=all>',
|
41
|
+
{_: :a, class: :down, href: e['uri'].E.url.t + e.q.except('triplr','view').qs, c: '↓'}]}
|
42
|
+
|
43
|
+
# user-patchable default-handler
|
44
|
+
fn '/GET',->e,r{
|
45
|
+
x = 'index.html'
|
46
|
+
i = [e,e.pathSegment].compact.map{|e|e.as x}.find &:e
|
47
|
+
if i
|
48
|
+
if e.uri[-1] == '/' # inside dir?
|
49
|
+
i.env(r).getFile # show index
|
50
|
+
else # descend to indexed dir
|
51
|
+
[301, {Location: e.uri.t}, []]
|
52
|
+
end
|
53
|
+
else
|
54
|
+
# default handler
|
55
|
+
e.response
|
56
|
+
end}
|
57
|
+
|
58
|
+
end
|
data/infod/Es/mail.rb
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
class E
|
2
|
+
|
3
|
+
# TMail version: 1.2.7.1-4 from:
|
4
|
+
# apt-get install ruby-tmail
|
5
|
+
|
6
|
+
def triplrTmail ; require 'tmail'
|
7
|
+
|
8
|
+
# read message
|
9
|
+
i = -> i {E i[1..-2]} # Message-ID -> E
|
10
|
+
(TMail::Mail.load node).do{|m| # parse
|
11
|
+
d = m.message_id; return unless d # parse successful?
|
12
|
+
e = i[d] # Message resource
|
13
|
+
|
14
|
+
# index previously unseen mail
|
15
|
+
e.e || ( # Message-ID locatable?
|
16
|
+
ln e # create message-id path
|
17
|
+
self.index Creator, m.from[0].E # index From
|
18
|
+
m.to.do{|t|self.index To, t[0].E} # index To
|
19
|
+
|
20
|
+
%w{in_reply_to references}.map{|p| m.send(p).do{|os| os.map{|o|
|
21
|
+
e.index SIOC+'reply_of', i[o]}}}) # index references
|
22
|
+
|
23
|
+
# yield triples
|
24
|
+
yield e.uri, Type, E[SIOCt + 'MailMessage']
|
25
|
+
yield e.uri, Type, E[SIOC + 'Post']
|
26
|
+
yield e.uri, Date, m.date.iso8601 if m.date
|
27
|
+
yield e.uri, Content, m.decentBody
|
28
|
+
[[:subject,Title],
|
29
|
+
[:to,To,true],
|
30
|
+
[:cc,To,true],
|
31
|
+
[:bcc,To,true],
|
32
|
+
[:friendly_from,SIOC+'name'],
|
33
|
+
[:from,Creator,true],
|
34
|
+
[:reply_to,'/mail/reply_to',true],
|
35
|
+
[:in_reply_to,'/parent',true,true],
|
36
|
+
[:in_reply_to,SIOC+'reply_of',true,true],
|
37
|
+
[:references,SIOC+'reply_of',true,true],
|
38
|
+
].each{|a| m.send(a[0]).do{|o| [*o].map{|o|
|
39
|
+
yield e.uri,a[1], # skip empty String values
|
40
|
+
(a[2] ? (a[3] ? i[o] : o.E) : o.to_utf8) unless o.match(/\A[, \n]*\Z/)}}}}
|
41
|
+
|
42
|
+
rescue Exception => e
|
43
|
+
puts [:mail,uri,e].join(' ')
|
44
|
+
end
|
45
|
+
|
46
|
+
alias_method :triplrMail, :triplrTmail
|
47
|
+
|
48
|
+
# pure-ruby mail is only 10x (vs 100x) slower than C-ext based TMail w/ new parser
|
49
|
+
# API is mostly identical, URIs strings arent <>-wrapped
|
50
|
+
# TODO replace this msg with triplrMail if anyone wants it
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
module TMail
|
55
|
+
class Mail
|
56
|
+
def unicode_body
|
57
|
+
unquoted_body.to_utf8
|
58
|
+
end
|
59
|
+
def decentBody
|
60
|
+
unHTML=->t{t.split(/<body[^>]*>/)[-1].split(/<\/body>/)[0]}
|
61
|
+
if multipart?
|
62
|
+
parts.collect{ |part|
|
63
|
+
c = part["content-type"]
|
64
|
+
if part.multipart?
|
65
|
+
part.decentBody
|
66
|
+
elsif header.nil?
|
67
|
+
""
|
68
|
+
elsif !attachment?(part) && c.sub_type != 'html'
|
69
|
+
part.unicode_body.hrefs(true)
|
70
|
+
else
|
71
|
+
(c["name"]||'attach').do{|a|
|
72
|
+
message_id ? (message_id[1..-2]+'/'+a).E.do{|i|
|
73
|
+
i.w part.body if !i.e
|
74
|
+
'<a href='+i.url+'>'+(part.main_type=='image' ? '<img src="'+i.url+'">' : a)+"</a><br>\n"
|
75
|
+
} : ""};end
|
76
|
+
}.join
|
77
|
+
|
78
|
+
else
|
79
|
+
unicode_body.do{|b|content_type&&content_type.match(/html/) ? unHTML.(b) : b.hrefs(true)}
|
80
|
+
end
|
81
|
+
rescue
|
82
|
+
''
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
class String; def is_binary_data?; true; end; end
|
data/infod/Es/man.rb
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
#watch __FILE__
|
2
|
+
class E
|
3
|
+
|
4
|
+
fn '/man/GET',->e,r{
|
5
|
+
manPath = '/usr/share/man'
|
6
|
+
|
7
|
+
# eat selector
|
8
|
+
name = e.pathSegment.uri.sub('/man/','/').tail
|
9
|
+
|
10
|
+
# section requested?
|
11
|
+
section = nil
|
12
|
+
name.match(/^([0-9])(\/|$)/).do{|p|
|
13
|
+
section = p[1]
|
14
|
+
name = p.post_match }
|
15
|
+
|
16
|
+
if !name || name.empty? || name.match(/\//)
|
17
|
+
if section
|
18
|
+
# enumerate section children
|
19
|
+
(H [H.css('/css/man'),{_: :style, c: "a {background-color: #{E.cs}}"},
|
20
|
+
Pathname(manPath+'/man'+section).c.map{|p|
|
21
|
+
n = p.basename.to_s.sub /\.[0-9][a-z]*\...$/,''
|
22
|
+
}.group_by{|e|e[0].match(/[a-zA-Z]/) ? e[0].downcase : '0-9'}.sort.map{|g,m|
|
23
|
+
[{_: :h3, c: g},
|
24
|
+
m.map{|n|[{_: :a, href: '/man/'+section+'/'+n, c: n },' ']}]}
|
25
|
+
]).hR
|
26
|
+
else
|
27
|
+
e.response
|
28
|
+
end
|
29
|
+
else
|
30
|
+
acceptLang = r['HTTP_ACCEPT_LANGUAGE'].do{|a|a.split(/,/)[0]}
|
31
|
+
lang = r.q['lang'] || acceptLang
|
32
|
+
superLang = lang.do{|l| (l.split /[_-]/)[0] }
|
33
|
+
langSH = lang.do{|l| '-L ' + l.sub('-','_').sh }
|
34
|
+
man = `man #{langSH} -w #{section} #{name.sh}`.chomp
|
35
|
+
|
36
|
+
if man.empty?
|
37
|
+
return false
|
38
|
+
else
|
39
|
+
|
40
|
+
roff = man.E
|
41
|
+
htmlBase = roff.dir.to_s.sub(/.*\/share/,'').E
|
42
|
+
html = htmlBase.as roff.bare + '.html'
|
43
|
+
cached = html.e && html.m > (Pathname man).stat.mtime
|
44
|
+
|
45
|
+
if !cached
|
46
|
+
|
47
|
+
locales = Pathname(manPath).c.select{|p|p.basename.to_s.do{|b| !b.match(/^man/) && !b.match(/\./) }}.map{|p|File.basename p}
|
48
|
+
localesAvail = locales.select{|l|
|
49
|
+
File.exist? manPath + '/' + l + '/' + roff.uri.split('/')[-2..-1].join('/')}
|
50
|
+
|
51
|
+
imagePath = htmlBase.d + '/images'
|
52
|
+
FileUtils.mkdir_p imagePath unless File.exist? imagePath
|
53
|
+
|
54
|
+
preconv = %w{hu pt tr}.member?(superLang) ? "" : "-k"
|
55
|
+
pageCmd = "zcat #{man} | groff #{preconv} -T html -man -P -D -P #{imagePath}"
|
56
|
+
page = `#{pageCmd}`#.to_utf8
|
57
|
+
|
58
|
+
[[:name,name],
|
59
|
+
[:acceptLang,acceptLang],
|
60
|
+
[:lang, lang],
|
61
|
+
[:langSH, langSH],
|
62
|
+
[:superLang, superLang],
|
63
|
+
[:roff,man],
|
64
|
+
[:htmlBase,htmlBase.d],
|
65
|
+
[:imagePath,imagePath],
|
66
|
+
[:localizations,localesAvail],
|
67
|
+
[:pageCmd,pageCmd]].map{|p| puts [" "*(13-p[0].size),*p].join ' ' }
|
68
|
+
|
69
|
+
page = Nokogiri::HTML.parse page
|
70
|
+
body = page.css('body')[0]
|
71
|
+
|
72
|
+
# add CSS link
|
73
|
+
body.add_child H H.css('/css/man')
|
74
|
+
body.add_child H[{_: :style, c: "a {background-color:#{E.cs}}"}]
|
75
|
+
|
76
|
+
# add localization links
|
77
|
+
(body.css('h1')[0] ||
|
78
|
+
body.css('p')[0]
|
79
|
+
).add_previous_sibling H localesAvail.map{|l|
|
80
|
+
{_: :a, class: :lang, href: r['REQUEST_PATH']+'?lang='+l, c: l}}
|
81
|
+
|
82
|
+
# webize image paths
|
83
|
+
body.css('img').map{|i|
|
84
|
+
p = (i.attr 'src').unpathFs
|
85
|
+
i.replace H[{_: :img, src: p}]}
|
86
|
+
|
87
|
+
# inspect plaintext
|
88
|
+
# HTMLize hyperlinks
|
89
|
+
# markup commands
|
90
|
+
body.xpath('//text()').map{|a|
|
91
|
+
a.replace a.to_s.gsub('>','>').hrefs.gsub /\b([^<>\s(]+)\(/mi, '<b>\1</b>('
|
92
|
+
}
|
93
|
+
|
94
|
+
qs = r['QUERY_STRING'].do{|q| q.empty? ? '' : '?' + q}
|
95
|
+
# href-ize commands
|
96
|
+
body.css('b').map{|b|
|
97
|
+
b.next.do{|n|
|
98
|
+
n.to_s.match(/\(([0-9])\)(.*)/).do{|section|
|
99
|
+
name, s = b.inner_text, section[1]
|
100
|
+
n.replace section[2]
|
101
|
+
b.replace " <a href='/man/#{s}/#{name}#{qs}'><b>#{name}</b>(#{s})</a>"}}}
|
102
|
+
|
103
|
+
html.w page
|
104
|
+
end
|
105
|
+
|
106
|
+
# response
|
107
|
+
html.env(r).getFile
|
108
|
+
end
|
109
|
+
end
|
110
|
+
}
|
111
|
+
|
112
|
+
end
|
data/infod/Es/mime.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
#watch __FILE__
|
2
|
+
class E
|
3
|
+
|
4
|
+
# MIME-type, no link-following
|
5
|
+
def mime
|
6
|
+
@mime ||=
|
7
|
+
(t = ext.downcase.to_sym
|
8
|
+
|
9
|
+
if node.symlink?
|
10
|
+
"inode/symlink"
|
11
|
+
|
12
|
+
elsif d?
|
13
|
+
"inode/directory"
|
14
|
+
|
15
|
+
elsif MIME[t]
|
16
|
+
MIME[t]
|
17
|
+
|
18
|
+
elsif Rack::Mime::MIME_TYPES[t='.'+t.to_s]
|
19
|
+
Rack::Mime::MIME_TYPES[t]
|
20
|
+
|
21
|
+
elsif base.index('msg.')==0
|
22
|
+
"message/rfc822"
|
23
|
+
|
24
|
+
elsif e
|
25
|
+
`file --mime-type -b #{sh}`.chomp
|
26
|
+
|
27
|
+
else
|
28
|
+
"application/octet-stream"
|
29
|
+
end)
|
30
|
+
end
|
31
|
+
|
32
|
+
# MIME-type of recursively-dereferenced path
|
33
|
+
def mimeP
|
34
|
+
@mime ||=
|
35
|
+
(p = realpath
|
36
|
+
|
37
|
+
unless p
|
38
|
+
nil
|
39
|
+
else
|
40
|
+
t = ((File.extname p).tail || '').downcase.to_sym
|
41
|
+
|
42
|
+
if p.directory?
|
43
|
+
"inode/directory"
|
44
|
+
|
45
|
+
elsif MIME[t]
|
46
|
+
MIME[t]
|
47
|
+
|
48
|
+
elsif Rack::Mime::MIME_TYPES[t='.'+t.to_s]
|
49
|
+
Rack::Mime::MIME_TYPES[t]
|
50
|
+
|
51
|
+
elsif (File.basename p).index('msg.')==0
|
52
|
+
"message/rfc822"
|
53
|
+
|
54
|
+
else
|
55
|
+
`file --mime-type -b #{Shellwords.escape p.to_s}`.chomp
|
56
|
+
end
|
57
|
+
end )
|
58
|
+
end
|
59
|
+
end
|
data/infod/Es/out.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
class E
|
2
|
+
|
3
|
+
def render mime, graph, e
|
4
|
+
E[Render+ mime].y graph, e
|
5
|
+
end
|
6
|
+
|
7
|
+
fn '/E/GET',->e,r{[301,{Location: '/'},[]]}
|
8
|
+
|
9
|
+
def response
|
10
|
+
|
11
|
+
q = @r.q # query-string
|
12
|
+
g = q['graph'] # graph-function selector
|
13
|
+
|
14
|
+
# empty response graph
|
15
|
+
m = {}
|
16
|
+
|
17
|
+
# identify graph
|
18
|
+
graphID = (F['protograph/' + g] || F['protograph/'])[self,q,m]
|
19
|
+
|
20
|
+
return F[E404][self,@r] if m.empty?
|
21
|
+
|
22
|
+
# identify response
|
23
|
+
@r['ETag'] ||= [graphID, q, @r.format, Watch].h
|
24
|
+
|
25
|
+
maybeSend @r.format, ->{
|
26
|
+
|
27
|
+
# response
|
28
|
+
r = E'/E/req/' + @r['ETag'].dive
|
29
|
+
if r.e # response exists
|
30
|
+
r # cached response
|
31
|
+
else
|
32
|
+
|
33
|
+
# graph
|
34
|
+
c = E '/E/graph/' + graphID.dive
|
35
|
+
if c.e # graph exists
|
36
|
+
m.merge! c.r true
|
37
|
+
else
|
38
|
+
# construct graph
|
39
|
+
(F['graph/' + g] || F['graph/'])[self,q,m]
|
40
|
+
# cache graph
|
41
|
+
c.w m,true
|
42
|
+
end
|
43
|
+
|
44
|
+
# graph sort/filter
|
45
|
+
E.filter q, m, self
|
46
|
+
|
47
|
+
# cache response
|
48
|
+
r.w render @r.format, m, @r
|
49
|
+
end }
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
@@ -1,8 +1,12 @@
|
|
1
1
|
#watch __FILE__
|
2
2
|
class E
|
3
3
|
|
4
|
-
fn 'head/page',->d,e{
|
5
|
-
|
4
|
+
fn 'head/page',->d,e{
|
5
|
+
v = e.q['v']
|
6
|
+
unless v == 'page'
|
7
|
+
h = F['head/'+v] || F['head']
|
8
|
+
h[d,e]
|
9
|
+
end}
|
6
10
|
|
7
11
|
fn 'view/page',->d,e{
|
8
12
|
# try daydirs if no pagination data provided
|
@@ -25,6 +29,6 @@ class E
|
|
25
29
|
|
26
30
|
[(H.js '/js/pager'),(H.once e,:mu,(H.js '/js/mu')), # n/p key shortcuts
|
27
31
|
c,(H (F['view/'+e.q['v']]||F['view']).(d,e)), # content
|
28
|
-
'<br clear=all>',c]}
|
32
|
+
'<br clear=all>',{class: :bottom, c: c}]}
|
29
33
|
|
30
34
|
end
|
data/infod/Es/pdf.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
class E
|
2
|
+
|
3
|
+
def triplrPDF &f
|
4
|
+
|
5
|
+
text = docBase.a '.txt'
|
6
|
+
unless text.e && text.m > m
|
7
|
+
puts "PDF #{uri}"
|
8
|
+
`pdftotext #{sh}`
|
9
|
+
end
|
10
|
+
|
11
|
+
# metadata
|
12
|
+
triplrStdOut 'pdfinfo', &f
|
13
|
+
|
14
|
+
# body
|
15
|
+
yield uri, Content, `cat #{text.sh}`
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
data/infod/Es/rdf.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
#watch __FILE__
|
2
|
+
class E
|
3
|
+
|
4
|
+
def self.renderRDF d,f
|
5
|
+
require 'linkeddata'
|
6
|
+
(RDF::Writer.for f).buffer{|w|
|
7
|
+
d.values.each{|r| r.triples{|s,p,o|
|
8
|
+
s = RDF::URI s
|
9
|
+
p = RDF::URI p
|
10
|
+
o = ([E,Hash].member?(o.class) ? (RDF::URI o.uri) : (RDF::Literal o)) rescue nil
|
11
|
+
(w << (RDF::Statement.new s,p,o) if o ) rescue nil
|
12
|
+
}}}
|
13
|
+
end
|
14
|
+
|
15
|
+
def triplrRDF format=:rdfa, localFile=true ; require 'linkeddata'
|
16
|
+
location = (localFile && f) ? d : uri
|
17
|
+
puts [:RDF,location].join ' '
|
18
|
+
RDF::Reader.open(location, :format => format){|r|
|
19
|
+
r.each_triple{|s,p,o|
|
20
|
+
yield s.to_s, p.to_s, [RDF::Node, RDF::URI].member?(o.class) ? E(o) : o.value.do{|v|v.class == String ? v.to_utf8 : v}}}
|
21
|
+
end
|
22
|
+
|
23
|
+
[['application/ld+json',:jsonld],
|
24
|
+
['application/json+ld',:jsonld],
|
25
|
+
['application/jsonld',:jsonld],
|
26
|
+
['application/rdf+xml',:rdfxml],
|
27
|
+
['application/rdfxml',:rdfxml],
|
28
|
+
['text/ntriples',:ntriples],
|
29
|
+
['text/turtle',:turtle],
|
30
|
+
['text/rdf+n3',:n3],
|
31
|
+
['text/n3',:n3]
|
32
|
+
].map{|mime|
|
33
|
+
F[Render+mime[0]] = ->d,a=nil{E.renderRDF d, mime[1]}}
|
34
|
+
|
35
|
+
end
|