infod 0.0.2 → 0.0.3.0

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.
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
@@ -2,20 +2,9 @@
2
2
  class E
3
3
 
4
4
  def triplrImage &f
5
+ yield uri,Type,E[DC+'Image']
5
6
  triplrStdOut 'exiftool', EXIF, &f
6
7
  end
7
-
8
- # export EXIF to RDF-in-JSON (recursive)
9
- def exif
10
- take.map{|g|
11
- if g.uri.match /(jpe?g|gif|png)$/i
12
- e = g.ef
13
- if !e.e || e.m < g.m
14
- g.ef.w g.fromStream({},:triplrImage), true
15
- puts "EXIF #{g} #{g.ef.size} bytes"
16
- end
17
- end}
18
- end
19
8
 
20
9
  fn 'req/scaleImage',->e,r{
21
10
  i = [e,e.pathSegment].compact.find(&:f)
@@ -38,17 +27,15 @@ class E
38
27
  end}
39
28
 
40
29
  fn 'view/img',->i,_{
41
- [i.values.map{|i|
42
- [{_: :a, href: i.url,
43
- c: {_: :img,
44
- style:'float:left;max-width:61.8%',
45
- src: i.url}},
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') &&
32
+ [{_: :a, href: i.url, c: {_: :img, style:'float:left;max-width:61.8%', src: i.url}},
46
33
  i.html]},
47
34
  (H.css '/css/img')]}
48
35
 
49
36
  fn 'view/th',->i,e{
50
- i.map{|u,i| u.match(/(gif|jpe?g|png|tiff)$/i) &&
51
- {_: :a, href: i.url+'?triplr=triplrImage&view=img',
37
+ i.map{|u,i| u && u.match(/(gif|jpe?g|png|tiff)$/i) &&
38
+ {_: :a, href: i.url+'?view=img',
52
39
  c: {_: :img, src: i.url+'?y=scaleImage&px=233'}}}}
53
40
 
54
41
  F['view/'+MIMEtype+'image/gif'] = F['view/th']
@@ -56,40 +43,43 @@ class E
56
43
  F['view/'+MIMEtype+'image/png'] = F['view/th']
57
44
 
58
45
  # display just the images found in content
59
- fn 'view/imgs',->m,e{
46
+ fn 'view/imgs',->m, e { seen = {}
60
47
 
61
- # height argument
48
+ # optional height argument
62
49
  h = e.q['h'].do{|h|
63
- h.match(/^[0-9]+$/).do{|_|'height:'+h+'px'}}
64
-
65
- # visited images
66
- seen={}
50
+ h.match(/^[0-9]+$/).do{|_|'height:'+h+'px'}}||''
67
51
 
68
52
  # extension-based filter
69
53
  x=->i{i&&i.match(/(jpe?g|gif|png)$/i)&&i}
70
54
 
71
55
  [(H.once e,:mu,H.js('/js/mu')),H.js('/js/images'),
72
56
  m.values.map{|v|
73
- # CSS selector-based search
57
+ # CSS-selector search inside content
74
58
  [[*v[Content]].map{|c| c.class == String &&
75
59
  (Nokogiri::HTML.parse(c).do{|c|
60
+
76
61
  [# <img> elements
77
62
  c.css('img').map{|i|i['src']}.compact,
63
+
78
64
  # <a> elements with image extensions
79
65
  c.css('a').map{|i|i['href']}.select(&x)]
80
66
  })},
67
+
81
68
  # check subject URI for image extension
82
69
  x.(v.uri),
70
+
83
71
  # check object URIs for image extension
84
72
  (v.respond_to?(:values) &&
85
73
  v.values.flatten.map{|v|
86
74
  v.respond_to?(:uri) && v.uri
87
75
  }.select(&x))
76
+
88
77
  ].flatten.uniq.compact.map{|s|
89
78
  # view
90
79
  {uri: s,
91
80
  # img and link to containing resource
92
81
  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|
82
+
93
83
  # show and mark as seen
94
84
  !seen[i[:uri]] &&
95
85
  (seen[i[:uri]] = true
@@ -1,18 +1,19 @@
1
- #watch __FILE__
1
+ watch __FILE__
2
2
  class E
3
3
 
4
4
  # POSIX-fs based index of triples
5
5
  #
6
6
 
7
- # index a triple
7
+ # index a triple
8
8
  def index p,o
9
9
  p = p.E
10
10
  indexEdit p, (o.class == E ? o : p.literal(o)), nil
11
11
  end
12
12
 
13
- # index a triple - no input type-normalization
13
+ # index a triple - no type-normalization
14
14
  def indexEdit p,o,a
15
15
  return if @noIndex
16
+ # puts "index #{p} #{o} #{a}"
16
17
  p.pIndex.noIndex[o,self,a]
17
18
  end
18
19
  def noIndex
@@ -22,6 +23,7 @@ class E
22
23
 
23
24
  # reachable graph along named predicate
24
25
  def walk p, g={}, v={}
26
+ # puts "walk #{uri}"
25
27
  graph g # cumulative graph
26
28
  v[uri] = true # visited mark
27
29
 
@@ -38,38 +40,47 @@ class E
38
40
  fn 'set/subtree',->d,r,m{
39
41
  c =(r['c'].do{|c|c.to_i + 1} || 3).max(100) # one extra for start of next-page
40
42
  o = r['d'] =~ /^a/ ? :asc : :desc # direction
43
+
41
44
  ('/'.E.take c, o, d.uri).do{|s| # take subtree
42
45
  desc, asc = o == :desc ? # orient pagination hints
43
46
  [s.pop, s[0]] : [s[0], s.pop]
44
- m['prev'] = {'uri' => 'prev', 'url' => desc.url,'d' => 'desc'}
45
- m['next'] = {'uri' => 'next', 'url' => asc.url, 'd' => 'asc'}
47
+ u = m['#']
48
+ u[Type] = E[HTTP+'Response']
49
+ u[Prev] = {'uri' => desc.url + {'d' => 'desc'}.qs} if desc
50
+ u[Next] = {'uri' => asc.url + {'d' => 'asc'}.qs} if asc
46
51
  s }}
47
52
 
48
53
  # subtree traverse index on p+o cursor
49
- fn 'set/index',->d,r,m,f=:rangePO{
50
- top = (f == :rangeP ? d : r['p']).expand.E
54
+ fn 'set/index',->d,r,m{
55
+ top = r['p'].expand.E
51
56
  count = r['c'] &&
52
- r['c'].to_i.max(1000)+1 || 22
53
- dir = r['d'] &&
54
- r['d'].match(/^(a|de)sc$/) &&
55
- r['d'].to_sym ||
56
- :desc
57
-
58
- (top.send f, count, dir, r['offset'],(d if f == :rangePO)).do{|s|
59
- # pagination pointers
60
- a,b = s[0], s.size > 1 && s.pop
61
- desc,asc = r['d'] && r['d']=='asc' && [a,b]||[b,a]
62
- # insert pointers in response-graph
63
- m['prev']={'uri' => 'prev','url' => d.url,'d' => 'desc','offset' => desc.uri} if desc
64
- m['next']={'uri' => 'next','url' => d.url,'d' => 'asc', 'offset' => asc.uri} if asc
65
- s }}
57
+ r['c'].to_i.max(1000) || 8
58
+ dir = r['d'] && r['d'].match(/^(a|de)sc$/) &&
59
+ r['d'].to_sym || :desc
60
+
61
+ (top.rangePO count+1, dir, r['offset'], r['o']).do{|s|
62
+ # orient pagination pointers
63
+ ascending = r['d'].do{|d| d == 'asc' }
64
+ first, last = s[0], s.size > 1 && s.pop
65
+ desc, asc = ascending && [first,last] || [last,first]
66
+ # response description
67
+ u = m['#']
68
+ u[RDFs+'member'] = s
69
+ u[Prev] = {'uri' => '/index/' + r['p'] + '/' + CGI.escape(r['o']) + {'offset' => desc.uri, 'c' => count}.qs } if desc
70
+ u[Next] = {'uri' => '/index/' + r['p'] + '/' + CGI.escape(r['o']) + {'offset' => asc.uri, 'c' => count}.qs } if asc
71
+
72
+ s.map(&:docs).flatten.uniq }}
66
73
 
67
- fn 'set/indexP',->d,r,m{Fn 'set/index',d,r,m,:rangeP}
68
- F['set/indexPO'] = F['set/index']
74
+ fn '/index/GET',->e,r{
75
+ a = e.pathSegment.uri[7..-1].split '/',2
76
+ r.q['set'] = 'index'
77
+ r.q['p'] = a[0]
78
+ r.q['o'] = CGI.unescape a[1]
79
+ e.response}
69
80
 
70
81
  # predicate index
71
82
  def pIndex
72
- prependURI '/index/'
83
+ shorten.prependURI '/index/'
73
84
  end
74
85
 
75
86
  # predicate-object index
@@ -83,8 +94,8 @@ class E
83
94
  end
84
95
 
85
96
  # range query - predicate
86
- def rangeP n=8,d=:desc,s=nil,o=nil
87
- pIndex.subtree(n,d,s).map &:ro
97
+ def rangeP size=8, dir=:desc, offset=nil, object=nil
98
+ pIndex.subtree(size,dir,offset).map &:ro
88
99
  end
89
100
 
90
101
  # range query - predicate-object
@@ -102,32 +113,17 @@ class E
102
113
  no.take(*a).map &:E
103
114
  end
104
115
 
105
- # random leaf
106
116
  def randomLeaf
107
117
  c.empty? && self || c.r.randomLeaf
108
118
  end
109
119
 
120
+ def E.graphProperties g
121
+ g.values.select{|v|v.respond_to? :keys}.map(&:keys).flatten.uniq
122
+ end
123
+
110
124
  fn 'set/randomLeaf',->d,e,m{[d.randomLeaf]}
111
125
  fn 'req/randomLeaf',->e,r{[302, {Location: e.randomLeaf.uri},[]]}
112
126
 
113
-
114
- # enumerate unique predicates in index
115
- fn '/index/GET',->e,r{
116
- e.pathSegment.uri.match(/^\/index$/) &&
117
- (H [{_: :style, c: "a {font-size:3em;display:block}
118
- a:hover {background-color:#00f}"},
119
- '/index'.E.take.map{|e|e.uri[6..-1].unpath.do{|p|{_: :a, href: '/@'+URI.escape(p.uri)+'?set=indexP&view=page&v=linkPO&c=12', c: p}}}]).hR}
120
-
121
- # p/o index-traversal pointers
122
- fn 'view/linkPO',->d,e{
123
- p = e['uri']
124
- [(H.css '/css/index'),(H.js '/js/search'),{_: :b, c: p},
125
- # front-end to search on SIOC predicate+object URIs
126
- %w{sioc:has_creator sioc:addressed_to}.member?(p).do{|_|
127
- {_: :form, action: '/whois',c: [{_: :input, type: :hidden, name: :p, value: p},{_: :input, name: :q}]}
128
- },
129
- d.map{|u,r| {c: {_: :a, href: r.url+'?set=indexPO&p=' + (URI.escape p) + '&view=page&views=timegraph,mail&v=multi&c=8', c: u}}}]}
130
-
131
127
  end
132
128
 
133
129
 
@@ -137,7 +133,7 @@ class Pathname
137
133
  def take count=1000, direction=:desc, offset=nil
138
134
 
139
135
  # construct offset-path
140
- offset = to_s + offset.gsub(/\/+/,'/').E.path if offset
136
+ offset = (to_s + offset).gsub(/\/+/,'/').E.path if offset
141
137
 
142
138
  # in-range indicator
143
139
  ok = false
@@ -151,7 +147,7 @@ class Pathname
151
147
 
152
148
  # visitation function
153
149
  visit=->nodes{
154
-
150
+
155
151
  # sort nodes in asc or desc order
156
152
  nodes.sort_by(&:to_s).send(v).each{|n|
157
153
  ns = n.to_s
@@ -174,8 +170,7 @@ class Pathname
174
170
  ok = true # iterator is now within range
175
171
  end )}}
176
172
 
177
- visit.(c) # start
178
-
173
+ visit.(c) # start
179
174
  # result set
180
175
  set
181
176
  end
data/infod/infod.rb CHANGED
@@ -1,12 +1,51 @@
1
-
2
- # the table of elements
3
-
4
- # Es infrastructure
5
- # H HTML
6
- # K constants
7
- # N naming
8
- # Rb Ruby native-types
9
- # Th HTTP
10
- # Y lambdas
11
-
12
- %w{Y K Rb N Es H Th}.map{|e| require 'infod/' + e}
1
+ %w{
2
+ constants
3
+ lambda
4
+ mime
5
+ 404
6
+ 500
7
+ audio
8
+ blog
9
+ cal
10
+ code
11
+ css
12
+ csv
13
+ du
14
+ edit
15
+ facets
16
+ feed
17
+ find
18
+ forum
19
+ fs
20
+ GET
21
+ glob
22
+ graph
23
+ grep
24
+ groonga
25
+ HEAD
26
+ histogram
27
+ html
28
+ HTTP
29
+ image
30
+ index
31
+ json
32
+ kv
33
+ ls
34
+ mail
35
+ man
36
+ microblog
37
+ names
38
+ page
39
+ PATCH
40
+ POST
41
+ postscript
42
+ rdf
43
+ ruby
44
+ schema
45
+ search
46
+ sh
47
+ text
48
+ threads
49
+ time
50
+ wiki
51
+ }.map{|e|require_relative e}
data/infod/json.rb ADDED
@@ -0,0 +1,38 @@
1
+ class Hash
2
+
3
+ def graph g
4
+ g.merge!({uri=>self})
5
+ end
6
+
7
+ def mergeGraph g
8
+ g.triples{|s,p,o|
9
+ self[s] = {'uri' => s} unless self[s].class == Hash
10
+ self[s][p] ||= []
11
+ self[s][p].push o unless self[s][p].member? o } if g
12
+ self
13
+ end
14
+
15
+ # self -> tripleStream
16
+ def triples &f
17
+ map{|s,r|
18
+ r.map{|p,o|
19
+ o.class == Array ? o.each{|o| yield s,p,o} : yield(s,p,o) unless p=='uri'} if r.class == Hash
20
+ }
21
+ end
22
+
23
+ end
24
+
25
+ class E
26
+
27
+ def triplrJSON
28
+ yield uri, '/application/json', (JSON.parse read) if e
29
+ rescue Exception => e
30
+ end
31
+
32
+ def to_json *a
33
+ to_h.to_json *a
34
+ end
35
+
36
+ fn Render+'application/json',->d,_=nil{[d].to_json}
37
+
38
+ end
@@ -27,17 +27,11 @@ class E
27
27
  unless t.e # triple exists?
28
28
  indexEdit p,o,nil # index triple
29
29
  if o.f # add triple
30
- # link resource
31
- # puts "link #{o} #{t}"
32
- o.ln t
30
+ o.ln t # hard link
33
31
  elsif o.e
34
- # symlink resource
35
- # puts "symlink #{o} #{t}"
36
- o.ln_s t
32
+ o.ln_s t # symbolic link
37
33
  else
38
- # name resource
39
- puts "origin missing #{t} , adding URI ref"
40
- t.mk
34
+ t.mk # dir entry
41
35
  end
42
36
  end
43
37
  end
@@ -5,6 +5,20 @@ def watch f
5
5
 
6
6
  class E
7
7
 
8
+ def initialize uri
9
+ @uri = uri.to_s
10
+ end
11
+
12
+ def E arg=nil
13
+ if arg
14
+ E.new arg
15
+ else
16
+ self
17
+ end
18
+ end
19
+
20
+ def E.[] u; u.E end
21
+
8
22
  F={}
9
23
  Watch={}
10
24
 
@@ -29,6 +43,9 @@ def fn u,y
29
43
  end
30
44
 
31
45
  def Fn a,*g
32
- puts "missing #{a} from #{caller[0]}" unless E::F[a]
33
46
  E::F[a][*g]
34
47
  end
48
+
49
+ def E e
50
+ E.new e
51
+ end
data/infod/ls.rb ADDED
@@ -0,0 +1,49 @@
1
+ #watch __FILE__
2
+ class E
3
+
4
+ fn 'view/dir',->i,e{
5
+ a = -> i { i = i.E
6
+ {_: :a, href: i.localURL(e), c: i.uri.match(/(gif|jpe?g|png)$/i) ? {_: :img, src: i.uri+'?y=scaleImage&px=233'} : i.uri.sub(/.*\//,'')}}
7
+
8
+ [(H.once e, 'dir', (H.css '/css/ls')),
9
+ i.map{|u,r|
10
+ url = r.E.localURL e
11
+ {class: :dir, style: "background-color: #{E.cs}", # dir wrapper
12
+ c: [{c: [{_: :a, href: url.t + '?view=ls', c: r.uri.sub('http://'+e['SERVER_NAME'],'')},
13
+ {_: :a, href: url.t, c: '/'}]},
14
+ r[Posix+'dir#child'].do{|c|c.map{|c|a[c]}}]}}]}
15
+
16
+ F['view/'+MIMEtype+'inode/directory'] = F['view/dir']
17
+
18
+ fn 'view/ls',->i,e{
19
+ dir = e['uri'].E
20
+ path = dir.pathSegment
21
+ up = (!path || path.uri == '/') ? '/' : dir.parent.url
22
+ i = i.dup
23
+ i.delete_if{|u,r|!r[Stat+'ftype']}
24
+ f = {}
25
+ ['uri', Posix+'dir#child', Stat+'ftype', Stat+'mtime', Stat+'size'].map{|p|f[p] = true}
26
+ i.values.map{|r|
27
+ r.class==Hash &&
28
+ r.delete_if{|p,o|!f[p]}}
29
+ [(H.css '/css/ls'),
30
+ {_: :a, class: :up, href: up+'?view=ls', c: '&uarr;'},
31
+ {class: :ls, c: (Fn 'view/table',i,e)},'<br clear=all>',
32
+ {_: :a, class: :down, href: e['uri'].E.url.t, c: '&darr;'}]}
33
+
34
+ # user-patchable default-handler
35
+ fn '/GET',->e,r{
36
+ x = 'index.html'
37
+ i = [e,e.pathSegment].compact.map{|e|e.as x}.find &:e
38
+ if i
39
+ if e.uri[-1] == '/' # inside dir?
40
+ i.env(r).getFile # show index
41
+ else # descend to indexed dir
42
+ [301, {Location: e.uri.t}, []]
43
+ end
44
+ else
45
+ # default handler
46
+ e.response
47
+ end}
48
+
49
+ end