infod 0.0.2 → 0.0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. data/infod.rb +51 -12
  2. data/infod/{Th/404.rb → 404.rb} +4 -16
  3. data/infod/500.rb +53 -0
  4. data/infod/GET.rb +104 -0
  5. data/infod/HEAD.rb +23 -0
  6. data/infod/HTTP.rb +105 -0
  7. data/infod/{Th/PATCH.rb → PATCH.rb} +0 -0
  8. data/infod/POST.rb +34 -0
  9. data/infod/audio.rb +30 -0
  10. data/infod/blog.rb +34 -0
  11. data/infod/cal.rb +72 -0
  12. data/infod/{Es/code.rb → code.rb} +7 -4
  13. data/infod/constants.rb +55 -0
  14. data/infod/{Es/css.rb → css.rb} +0 -0
  15. data/infod/{Es/csv.rb → csv.rb} +0 -0
  16. data/infod/{Es/du.rb → du.rb} +0 -0
  17. data/infod/edit.rb +73 -0
  18. data/infod/{H/facets.rb → facets.rb} +20 -11
  19. data/infod/{Es/feed.rb → feed.rb} +17 -16
  20. data/infod/{Es/find.rb → find.rb} +2 -3
  21. data/infod/forum.rb +13 -0
  22. data/infod/{Es/fs.rb → fs.rb} +5 -2
  23. data/infod/glob.rb +26 -0
  24. data/infod/graph.rb +131 -0
  25. data/infod/{Es/grep.rb → grep.rb} +3 -3
  26. data/infod/{Es/groonga.rb → groonga.rb} +35 -26
  27. data/infod/{H/histogram.rb → histogram.rb} +23 -16
  28. data/infod/html.rb +231 -0
  29. data/infod/{Es/image.rb → image.rb} +16 -26
  30. data/infod/{Es/index.rb → index.rb} +44 -49
  31. data/infod/infod.rb +51 -12
  32. data/infod/json.rb +38 -0
  33. data/infod/{Es/kv.rb → kv.rb} +3 -9
  34. data/infod/{Y.rb → lambda.rb} +18 -1
  35. data/infod/ls.rb +49 -0
  36. data/infod/mail.rb +108 -0
  37. data/infod/{Es/man.rb → man.rb} +3 -15
  38. data/infod/{H/microblog.rb → microblog.rb} +22 -31
  39. data/infod/{K.rb → mime.rb} +68 -52
  40. data/infod/{N.rb → names.rb} +77 -56
  41. data/infod/page.rb +13 -0
  42. data/infod/postscript.rb +26 -0
  43. data/infod/rdf.rb +51 -0
  44. data/infod/{Rb.rb → ruby.rb} +18 -33
  45. data/infod/{Es/schema.rb → schema.rb} +23 -8
  46. data/infod/{Es/search.rb → search.rb} +5 -11
  47. data/infod/{Es/sh.rb → sh.rb} +0 -0
  48. data/infod/{Es/text.rb → text.rb} +33 -29
  49. data/infod/{H/threads.rb → threads.rb} +20 -27
  50. data/infod/{H/time.rb → time.rb} +14 -34
  51. data/infod/{H/wiki.rb → wiki.rb} +0 -0
  52. metadata +53 -64
  53. data/config.ru +0 -3
  54. data/infod/Es.rb +0 -31
  55. data/infod/Es/filter.rb +0 -75
  56. data/infod/Es/glob.rb +0 -22
  57. data/infod/Es/html.rb +0 -271
  58. data/infod/Es/in.rb +0 -68
  59. data/infod/Es/json.rb +0 -68
  60. data/infod/Es/ls.rb +0 -58
  61. data/infod/Es/mail.rb +0 -87
  62. data/infod/Es/mime.rb +0 -59
  63. data/infod/Es/out.rb +0 -52
  64. data/infod/Es/pager.rb +0 -34
  65. data/infod/Es/pdf.rb +0 -19
  66. data/infod/Es/rdf.rb +0 -35
  67. data/infod/H.rb +0 -15
  68. data/infod/H/audio.rb +0 -19
  69. data/infod/H/blog.rb +0 -15
  70. data/infod/H/cal.rb +0 -81
  71. data/infod/H/edit.rb +0 -88
  72. data/infod/H/forum.rb +0 -4
  73. data/infod/H/hf.rb +0 -114
  74. data/infod/H/mail.rb +0 -92
  75. data/infod/H/who.rb +0 -30
  76. data/infod/Th.rb +0 -36
  77. data/infod/Th/500.rb +0 -41
  78. data/infod/Th/GET.rb +0 -62
  79. data/infod/Th/HEAD.rb +0 -5
  80. data/infod/Th/POST.rb +0 -39
  81. data/infod/Th/perf.rb +0 -37
  82. data/infod/Th/uid.rb +0 -24
  83. data/infod/Th/util.rb +0 -89
data/infod/Es/in.rb DELETED
@@ -1,68 +0,0 @@
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/json.rb DELETED
@@ -1,68 +0,0 @@
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
-
25
- class E
26
-
27
- def triplrJSON
28
- yield uri, '/application/json', (JSON.parse read) if e
29
- end
30
-
31
-
32
- # tripleStream -> fs
33
- def addJSON i,g,p=[]
34
- fromStream({},i).map{|u,r| # stream -> graph
35
- (E u).do{|e| # resource
36
- j = e.ef # inode
37
- j.e || # exists?
38
- (p.map{|p|r[p].do{|o|e.index p,o[0]}} # index properties
39
- j.w({u => r},true) # write doc
40
- puts "a #{e}"
41
- # link opaque-URI docs as siblings of base-URI for doc-discoverability
42
- e.a('.e').do{|u| (j.ln u) unless ((j.uri == u.uri) || u.e) }
43
- e.roonga g # index content
44
- )}}
45
- self
46
- rescue Exception => e
47
- puts "addJSON #{e}"
48
- end
49
-
50
- fn 'view/application/json',->m,e{
51
- m.map{|u,j|
52
- e.q['sel'].do{|s|
53
- c = j['/application/json'][0]
54
- s.split(/\./).map{|s|
55
- s = s.to_i if s.match(/^\d$/)
56
- c = c[s] }
57
- [{_: :a,
58
- href: u+'?q=json&view=application/json&sel='+s,
59
- c: {_: :b, c: u+'#'+s}}, c.html]
60
- }||[{_: :h3, c: u},j.html]}}
61
-
62
- def to_json *a
63
- to_h.to_json *a
64
- end
65
-
66
- fn Render+'application/json',->d,_=nil{[d].to_json}
67
-
68
- end
data/infod/Es/ls.rb DELETED
@@ -1,58 +0,0 @@
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: '&darr;'}]}
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 DELETED
@@ -1,87 +0,0 @@
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/mime.rb DELETED
@@ -1,59 +0,0 @@
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 DELETED
@@ -1,52 +0,0 @@
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
data/infod/Es/pager.rb DELETED
@@ -1,34 +0,0 @@
1
- #watch __FILE__
2
- class E
3
-
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}
10
-
11
- fn 'view/page',->d,e{
12
- # try daydirs if no pagination data provided
13
- !d.has_any_key(%w{next prev}) &&
14
- e['REQUEST_PATH'].match(/(.*?\/)([0-9]{4})\/([0-9]{2})\/([0-9]{2})(.*)/).do{|m|
15
- t = ::Date.parse "#{m[2]}-#{m[3]}-#{m[4]}"
16
- d['prev'] = {'uri' => 'prev','url' => m[1]+(t-1).strftime('%Y/%m/%d')+m[5]}
17
- d['next'] = {'uri' => 'next','url' => m[1]+(t+1).strftime('%Y/%m/%d')+m[5]}}
18
-
19
- # links
20
- c=[d['prev'].do{|p| d.delete('prev') # prev
21
- {_: :a, rel: :prev, style: 'float:left; font-size:2em',
22
- href: [*p['url']][0]+e.q.merge(p).except('uri','url').qs,
23
- title: (p['b']||p['url']), c: '&larr;'}},
24
-
25
- d['next'].do{|n| d.delete('next') # next
26
- {_: :a, rel: :next, style: 'float:right;font-size:2em',
27
- href: [*n['url']][0]+e.q.merge(n).except('uri','url').qs,
28
- title: (n['b']||n['url']), c: '&rarr;'}}]
29
-
30
- [(H.js '/js/pager'),(H.once e,:mu,(H.js '/js/mu')), # n/p key shortcuts
31
- c,(H (F['view/'+e.q['v']]||F['view']).(d,e)), # content
32
- '<br clear=all>',{class: :bottom, c: c}]}
33
-
34
- end
data/infod/Es/pdf.rb DELETED
@@ -1,19 +0,0 @@
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