infod 0.0.2 → 0.0.3

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 +52 -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 +123 -0
  25. data/infod/{Es/grep.rb → grep.rb} +2 -2
  26. data/infod/{Es/groonga.rb → groonga.rb} +41 -33
  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} +38 -25
  31. data/infod/infod.rb +52 -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 +90 -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} +78 -45
  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} +22 -7
  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} +17 -27
  50. data/infod/{H/time.rb → time.rb} +14 -34
  51. data/infod/{H/who.rb → whois.rb} +6 -4
  52. data/infod/{H/wiki.rb → wiki.rb} +0 -0
  53. metadata +54 -64
  54. data/config.ru +0 -3
  55. data/infod/Es.rb +0 -31
  56. data/infod/Es/filter.rb +0 -75
  57. data/infod/Es/glob.rb +0 -22
  58. data/infod/Es/html.rb +0 -271
  59. data/infod/Es/in.rb +0 -68
  60. data/infod/Es/json.rb +0 -68
  61. data/infod/Es/ls.rb +0 -58
  62. data/infod/Es/mail.rb +0 -87
  63. data/infod/Es/mime.rb +0 -59
  64. data/infod/Es/out.rb +0 -52
  65. data/infod/Es/pager.rb +0 -34
  66. data/infod/Es/pdf.rb +0 -19
  67. data/infod/Es/rdf.rb +0 -35
  68. data/infod/H.rb +0 -15
  69. data/infod/H/audio.rb +0 -19
  70. data/infod/H/blog.rb +0 -15
  71. data/infod/H/cal.rb +0 -81
  72. data/infod/H/edit.rb +0 -88
  73. data/infod/H/forum.rb +0 -4
  74. data/infod/H/hf.rb +0 -114
  75. data/infod/H/mail.rb +0 -92
  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
@@ -4,13 +4,13 @@ class E
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
16
  p.pIndex.noIndex[o,self,a]
@@ -22,6 +22,7 @@ class E
22
22
 
23
23
  # reachable graph along named predicate
24
24
  def walk p, g={}, v={}
25
+ # puts "walk #{uri}"
25
26
  graph g # cumulative graph
26
27
  v[uri] = true # visited mark
27
28
 
@@ -38,16 +39,19 @@ class E
38
39
  fn 'set/subtree',->d,r,m{
39
40
  c =(r['c'].do{|c|c.to_i + 1} || 3).max(100) # one extra for start of next-page
40
41
  o = r['d'] =~ /^a/ ? :asc : :desc # direction
42
+
41
43
  ('/'.E.take c, o, d.uri).do{|s| # take subtree
42
44
  desc, asc = o == :desc ? # orient pagination hints
43
45
  [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'}
46
+ u = m['#']
47
+ u[Type] = E[HTTP+'Response']
48
+ u[Prev] = {'uri' => desc.url + {'d' => 'desc'}.qs} if desc
49
+ u[Next] = {'uri' => asc.url + {'d' => 'asc'}.qs} if asc
46
50
  s }}
47
51
 
48
52
  # subtree traverse index on p+o cursor
49
53
  fn 'set/index',->d,r,m,f=:rangePO{
50
- top = (f == :rangeP ? d : r['p']).expand.E
54
+ top = (f == :rangeP ? d : (r['p'] || '/')).expand.E
51
55
  count = r['c'] &&
52
56
  r['c'].to_i.max(1000)+1 || 22
53
57
  dir = r['d'] &&
@@ -56,20 +60,25 @@ class E
56
60
  :desc
57
61
 
58
62
  (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 }}
63
+ # orient pagination pointers
64
+ ascending = r['d'].do{|d| d == 'asc' }
65
+ first, last = s[0], s.size > 1 && s.pop
66
+ desc, asc = ascending && [first,last] || [last,first]
67
+
68
+ # response description
69
+ u = m['#']
70
+ u[RDFs+'member'] = s
71
+ u[Prev] = {'uri' => d.url + {'d' => 'desc','offset' => desc.uri}.qs} if desc
72
+ u[Next] = {'uri' => d.url + {'d' => 'asc', 'offset' => asc.uri}.qs} if asc
73
+
74
+ s.map(&:docs).flatten.uniq }}
66
75
 
67
76
  fn 'set/indexP',->d,r,m{Fn 'set/index',d,r,m,:rangeP}
68
- F['set/indexPO'] = F['set/index']
77
+ F['set/indexPO'] = F['set/index']
69
78
 
70
79
  # predicate index
71
80
  def pIndex
72
- prependURI '/index/'
81
+ shorten.prependURI '/index/'
73
82
  end
74
83
 
75
84
  # predicate-object index
@@ -83,8 +92,8 @@ class E
83
92
  end
84
93
 
85
94
  # range query - predicate
86
- def rangeP n=8,d=:desc,s=nil,o=nil
87
- pIndex.subtree(n,d,s).map &:ro
95
+ def rangeP size=8, dir=:desc, offset=nil, object=nil
96
+ pIndex.subtree(size,dir,offset).map &:ro
88
97
  end
89
98
 
90
99
  # range query - predicate-object
@@ -102,23 +111,25 @@ class E
102
111
  no.take(*a).map &:E
103
112
  end
104
113
 
105
- # random leaf
106
114
  def randomLeaf
107
115
  c.empty? && self || c.r.randomLeaf
108
116
  end
109
117
 
118
+ def E.graphProperties g
119
+ g.values.select{|v|v.respond_to? :keys}.map(&:keys).flatten.uniq
120
+ end
121
+
110
122
  fn 'set/randomLeaf',->d,e,m{[d.randomLeaf]}
111
123
  fn 'req/randomLeaf',->e,r{[302, {Location: e.randomLeaf.uri},[]]}
112
124
 
113
-
114
125
  # enumerate unique predicates in index
115
126
  fn '/index/GET',->e,r{
116
127
  e.pathSegment.uri.match(/^\/index$/) &&
117
128
  (H [{_: :style, c: "a {font-size:3em;display:block}
118
129
  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}
130
+ '/index'.E.take.map{|e|e.uri[6..-1].unpath.do{|p|{_: :a, href: '/@'+URI.escape(p.uri)+'?set=indexP&c=12', c: p}}}]).hR}
120
131
 
121
- # p/o index-traversal pointers
132
+ # p+o index-traversal pointers
122
133
  fn 'view/linkPO',->d,e{
123
134
  p = e['uri']
124
135
  [(H.css '/css/index'),(H.js '/js/search'),{_: :b, c: p},
@@ -126,7 +137,10 @@ a:hover {background-color:#00f}"},
126
137
  %w{sioc:has_creator sioc:addressed_to}.member?(p).do{|_|
127
138
  {_: :form, action: '/whois',c: [{_: :input, type: :hidden, name: :p, value: p},{_: :input, name: :q}]}
128
139
  },
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}}}]}
140
+ # set members
141
+ d['#'][RDFs+'member'].do{|m|
142
+ m.map{|r|
143
+ {c: {_: :a, href: r.url+'?set=indexPO&p=' + (URI.escape p) + '&c=8', c: r.uri}}}}]}
130
144
 
131
145
  end
132
146
 
@@ -137,7 +151,7 @@ class Pathname
137
151
  def take count=1000, direction=:desc, offset=nil
138
152
 
139
153
  # construct offset-path
140
- offset = to_s + offset.gsub(/\/+/,'/').E.path if offset
154
+ offset = (to_s + offset).gsub(/\/+/,'/').E.path if offset
141
155
 
142
156
  # in-range indicator
143
157
  ok = false
@@ -151,7 +165,7 @@ class Pathname
151
165
 
152
166
  # visitation function
153
167
  visit=->nodes{
154
-
168
+
155
169
  # sort nodes in asc or desc order
156
170
  nodes.sort_by(&:to_s).send(v).each{|n|
157
171
  ns = n.to_s
@@ -174,8 +188,7 @@ class Pathname
174
188
  ok = true # iterator is now within range
175
189
  end )}}
176
190
 
177
- visit.(c) # start
178
-
191
+ visit.(c) # start
179
192
  # result set
180
193
  set
181
194
  end
data/infod/infod.rb CHANGED
@@ -1,12 +1,52 @@
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
+ whois
51
+ wiki
52
+ }.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