infod 0.0.3.2 → 0.0.3.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 06750f111d49bb2b62f28cd18bc35dd5212dc0ac
4
+ data.tar.gz: 7ee2db920696465b43201741aa28e6ecaf64af41
5
+ SHA512:
6
+ metadata.gz: 03d0d7ae6b88af73a4d5054e2736764d46d5e3247284bcbda919c811182ab0bdbf4e2ef37ccd5fdd8228f4435f3bc6f23311f6f6ac41a9f70016338e4bc6a01c
7
+ data.tar.gz: ff95efae2b1690cd8f244360e903d1f9a7ea287a2450cdcb85e418b1f444eed54d9601819f4a266897ba0409711ad5af572f984f65a9b076395c2cf690a26cdb
data/bin/infod CHANGED
@@ -28,7 +28,7 @@ module Rack
28
28
  def self.load _
29
29
  Rack::Builder.new {
30
30
  use Rack::Deflater
31
- run E
31
+ run R
32
32
  }.to_app
33
33
  end
34
34
  end
data/infod.rb CHANGED
@@ -1,3 +1,17 @@
1
+ %w{
2
+ cgi
3
+ date
4
+ digest/sha1
5
+ fileutils
6
+ json
7
+ linkeddata
8
+ mail
9
+ nokogiri
10
+ open-uri
11
+ pathname
12
+ rack
13
+ shellwords}.map{|r|require r}
14
+
1
15
  %w{
2
16
  constants
3
17
  lambda
@@ -13,34 +27,25 @@ csv
13
27
  edit
14
28
  facets
15
29
  feed
16
- find
17
30
  forum
18
31
  fs
19
32
  GET
20
- glob
21
33
  graph
22
34
  groonga
23
- HEAD
24
35
  histogram
25
36
  html
26
37
  HTTP
27
38
  image
28
39
  index
29
- kv
30
40
  ls
31
41
  mail
32
42
  man
33
43
  microblog
34
44
  names
35
- page
36
45
  POST
37
- postscript
38
46
  rdf
39
- ruby
40
47
  schema
41
- sh
42
48
  text
43
49
  threads
44
50
  time
45
- wiki
46
51
  }.map{|e|require_relative e}
@@ -1,4 +1,4 @@
1
- class E
1
+ class R
2
2
 
3
3
  E404 = 'req/'+HTTP+'404'
4
4
 
@@ -13,18 +13,20 @@ r.map{|k,v| s[Header + k] = k == 'uri' ? v : [v] }
13
13
  %w{CHARSET LANGUAGE ENCODING}.map{|a|
14
14
  s[Header+'ACCEPT_'+a] = [r.accept_('_' + a)]}
15
15
  s[Header+'ACCEPT'] = [r.accept]
16
- s[Type] = [E[HTTP+'Response']]
16
+ s[Type] = [R[HTTP+'Response']]
17
17
  s[HTTP+'statusCodeValue'] = [404]
18
- s[Header+'HTTP_HOST'] = [E['http://' + s[Header+'HTTP_HOST'][0]]] if s[Header+'HTTP_HOST']
19
- s[Edit] = [E[r['REQUEST_PATH']+'?graph=create']]
18
+ s[Header+'HTTP_HOST'] = [R['http://' + s[Header+'HTTP_HOST'][0]]] if s[Header+'HTTP_HOST']
19
+ s[Edit] = [R[r['REQUEST_PATH']+'?graph=create']]
20
20
  s['#query'] = [r.q]
21
21
  s['#seeAlso'] = [e.parent,*e.a('*').glob]
22
22
  r.q['view'] = '404'
23
23
 
24
24
  [404,{'Content-Type'=> r.format},[e.render(r.format,g,r)]]}
25
-
25
+
26
+ F['/cache/GET'] = F[E404]
27
+
26
28
  fn 'view/404',->d,e{
27
- [H.css('/css/404'),{_: :style, c: "a {background-color:#{E.cs}}"},
29
+ [H.css('/css/404'),{_: :style, c: "a {background-color:#{R.cs}}"},
28
30
  d.html]}
29
31
 
30
32
  # a resource-placeholder graph
@@ -32,4 +34,15 @@ s[HTTP+'statusCodeValue'] = [404]
32
34
  m[d.uri] = {}
33
35
  rand.to_s.h}
34
36
 
37
+ def checkURIs
38
+ r = uris.map{|u|
39
+ c = [`curl -IsA 404? "#{u}"`.lines.to_a[0].match(/\d{3}/)[0].to_i,u] # HEAD
40
+ puts c.join ' '
41
+ c } # status, uri tuple
42
+ puts "\n\n"
43
+ r.map{|c|
44
+ # show anomalies
45
+ puts c.join(' ') unless c[0] == 200 }
46
+ end
47
+
35
48
  end
@@ -1,5 +1,5 @@
1
1
  #watch __FILE__
2
- class E
2
+ class R
3
3
 
4
4
  Errors ||= {}
5
5
 
@@ -44,7 +44,7 @@ h1 {padding:.2em; background-color:#f00; color:#fff; margin:0}
44
44
  div {display:inline}
45
45
  table {border-spacing:0;margin:0}
46
46
  b {background-color:#eee;color:#500;padding:.1em .3em .1em .3em}
47
- .frag {font-weight:bold; color:#000; background-color:#{E.cs}}
47
+ .frag {font-weight:bold; color:#000; background-color:#{R.cs}}
48
48
  td.space {background-color:#ddd}
49
49
  td.message {background-color:#009;color:#fff}
50
50
  td.path {text-align:right}
@@ -1,4 +1,4 @@
1
- class E
1
+ class R
2
2
 
3
3
  Apache = ENV['apache']
4
4
  Nginx = ENV['nginx']
@@ -21,6 +21,14 @@ class E
21
21
  end
22
22
  end
23
23
 
24
+ def HEAD
25
+ self.GET.do{|s,h,b|[s,h,[]]}
26
+ end
27
+
28
+ def OPTIONS
29
+ [200,{},[]]
30
+ end
31
+
24
32
  def getFile
25
33
  @r['ETag'] = [m,size].h
26
34
  maybeSend mimeP,->{self}
@@ -52,25 +60,19 @@ class E
52
60
  @r['ETag'] ||= [@r.q['view'].do{|v|F['view/' + v] && v}, graphID, @r.format, Watch].h
53
61
 
54
62
  maybeSend @r.format, ->{
55
-
56
- # response
57
- r = E'/E/req/' + @r['ETag'].dive
58
- if r.e # exists
63
+
64
+ r = R '/cache/view/' + @r['ETag'].dive
65
+ if r.e # exists?
59
66
  r
60
67
  else
61
-
62
- # graph
63
- c = E '/E/graph/' + graphID.dive
64
- if c.e # exists
68
+ c = R '/cache/model/' + graphID.dive
69
+ if c.e # exists?
65
70
  m = c.r true
66
71
  else
67
- # construct
68
- (g && F['graph/' + g] || F['graph/'])[self, @r.q,m]
69
- # cache
70
- c.w m,true
72
+ (g && F['graph/' + g] || F['graph/'])[self, @r.q,m] # construct
73
+ c.w m,true # cache
71
74
  end
72
- # cache < construct
73
- r.w render @r.format, m, @r
75
+ r.w render @r.format, m, @r # construct -> cache
74
76
  end }
75
77
  end
76
78
 
@@ -85,7 +87,7 @@ class E
85
87
  h.update({'Cache-Control' => 'no-transform'}) if m.match /^(audio|image|video)/ # already compresed
86
88
 
87
89
  # frontend-specific handlers
88
- b.class == E ? (Nginx ? # nginx chosen?
90
+ b.class == R ? (Nginx ? # nginx chosen?
89
91
  [c,h.update({'X-Accel-Redirect' => '/fs' + b.path}),[]] : # Nginx handler
90
92
  Apache ? # Apache chosen?
91
93
  [c,h.update({'X-Sendfile' => b.d}),[]] : # Apache handler
@@ -1,14 +1,12 @@
1
1
  #watch __FILE__
2
- require 'rack'
2
+ class R
3
3
 
4
- class E
5
-
6
- def E.call e
7
- e.extend Th # add HTTP utility functions to environment table
4
+ def R.call e
5
+ e.extend Th # HTTP utility functions
8
6
  dev # see if watched files were changed
9
7
  e['HTTP_X_FORWARDED_HOST'].do{|h| e['SERVER_NAME'] = h }
10
8
  path = CGI.unescape e['REQUEST_PATH'].force_encoding('UTF-8').gsub '+','%2B'
11
- resource = E['http://'+e['SERVER_NAME']+path]
9
+ resource = R['http://'+e['SERVER_NAME']+path]
12
10
 
13
11
  if resource.inside
14
12
  e['uri'] = resource.uri
@@ -66,7 +64,7 @@ module Th
66
64
  # Accept formats
67
65
  accept.sort.reverse.map{|q,mimes|
68
66
  mimes.map{|mime|
69
- return mime if E::F[E::Render+mime]}}
67
+ return mime if R::F[R::Render+mime]}}
70
68
  'text/html'
71
69
  end
72
70
 
@@ -1,31 +1,38 @@
1
- watch __FILE__
2
- class E
1
+ #watch __FILE__
2
+ class R
3
3
 
4
4
  def POST
5
- type = @r['CONTENT_TYPE']
6
- case type
7
- when /^application\/sparql-update/
8
- puts "SPARQL"
5
+ # custom handler lookup cascade
6
+ pathSegment.do{|path|
7
+ lambdas = path.cascade.map{|p| p.uri.t + 'POST' }
8
+ ['http://'+@r['SERVER_NAME'],""].map{|h| lambdas.map{|p|
9
+ F[h + p].do{|fn| fn[self,@r].do{|r|
10
+ $stdout.puts [r[0],'http://'+@r['SERVER_NAME']+@r['REQUEST_URI'],@r['HTTP_USER_AGENT'],@r['HTTP_REFERER'],@r.format].join ' '
11
+ return r
12
+ }}}}}
13
+ basicPOST
14
+ end
15
+ def basicPOST
16
+ return [303,{'Location'=>uri},[]]
17
+ case @r['CONTENT_TYPE']
9
18
  when /^application\/x-www-form-urlencoded/
10
19
  changed = false
11
- (Rack::Request.new @r).params.map{|k,v|
12
- s, p, o = (CGI.unescape k).split /\/\._/
13
- if s && p && o
14
- s, p, o = [s, p, o].map &:unpath
15
- if s.uri.match(/^http/) && p.uri.match(/^http/)
16
- oO = v.match(/\A(\/|http)[\S]+\Z/) ? v.E : F['cleanHTML'][v]
17
- if o != oO
18
- changed = true
19
- s[p,o,oO]
20
- end
21
- end
20
+ (Rack::Request.new @r).params.map{|k,v| s, p, tripleA = JSON.parse CGI.unescape k
21
+ s = s.R
22
+ pp = s.predicatePath p
23
+ o = v.match(/\A(\/|http)[\S]+\Z/) ? v.R : F['cleanHTML'][v]
24
+ tripleB = pp.objectPath(o)[0]
25
+ if tripleA.to_s != tripleB.to_s
26
+ tripleA && tripleA.R.do{|t| t.delete if t.e }
27
+ s[p] = o unless o.class==String && o.empty?
28
+ changed = true
22
29
  end}
23
30
  if changed
24
31
  g = {}
25
32
  fromStream g, :triplrDoc
26
- if g.empty?
27
- ef.deleteNode
28
- else
33
+ if g.empty? # no triples left
34
+ ef.delete
35
+ else # snapshot to graph-doc
29
36
  ef.w g, true
30
37
  end
31
38
  end
@@ -1,4 +1,4 @@
1
- class E
1
+ class R
2
2
 
3
3
  VideoFile = /(avi|flv|mkv|mpg|mp4|wmv)$/i
4
4
  AudioFile = /(aif|wav|flac|mp3|m4a|aac|ogg)$/i
@@ -1,29 +1,46 @@
1
1
  #watch __FILE__
2
- class E
2
+ class R
3
3
 
4
- F['view/'+SIOCt+'BlogPost']=->g,e{
4
+ F['/blog/post/POST'] = -> d,e {
5
+ name = URI.escape (Rack::Request.new d.env).params['name'].gsub /[?#\s\/]/,'_'
6
+ doc = 'http://'+e['SERVER_NAME']+Time.now.strftime('/%Y/%m/')+name
7
+ post = doc.R.a '#'
8
+ post[Type] = R[SIOCt+'BlogPost']
9
+ post[Title] = name
10
+ edit = "?prototype=sioct:BlogPost&graph=edit"
11
+ [303,{'Location' => doc + edit},[]]}
5
12
 
6
- F['example/blogview'][g,e]
13
+ F['/blog/post/GET'] = -> d,e {
14
+ [200,{'Content-Type'=>'text/html'},
15
+ [H(['name',
16
+ {_: :form, method: :POST,
17
+ c: [{_: :input, name: :name, style: "font-size:1.6em;width:48ex"},
18
+ {_: :input, type: :submit, value: ' go '}
19
+ ]}])]]}
7
20
 
8
- }
21
+ F['view/'+SIOCt+'BlogPost']=->g,e{F['example/blogview'][g,e]}
9
22
 
10
23
  F['example/blogview']=->g,e{
11
24
  g.map{|u,r|
12
- case u
25
+ case u # match against URIs for customized view
13
26
  when /artery.wbur/ # compact whitespace a bit
14
27
  r[Content] = {class: :WBUR, c: [{_: :style, c: ".WBUR p {margin:0}"},r[Content]]}
15
28
  F['view/base'][{u => r},e,false]
29
+
16
30
  when /boston\.com/ # crop sharebuttons
17
31
  (Nokogiri::HTML.parse r[Content][0]).css('p')[0].do{|p|r[Content]=p.inner_html}
18
32
  F['view/base'][{u => r},e,false]
33
+
19
34
  when /flickr/
20
35
  r[Content]
36
+
21
37
  when /reddit/ # minimal view
22
38
  F['view/'+SIOCt+'BoardPost'][{u => r},e]
39
+
23
40
  when /universalhub/ # logo + trim spacehogging tagjunk
24
41
  c = Nokogiri::HTML.fragment r[Content][0]
25
42
  c.css('section').map{|x|x.remove}
26
- {c: [{_: :a, href: r['http://purl.org/rss/1.0/link'][0].E.uri,
43
+ {c: [{_: :a, href: r['http://purl.org/rss/1.0/link'][0].R.uri,
27
44
  c: [{_: :img, src: '/logos/uhub.png',style: 'position:absolute;top:-93px'},
28
45
  {_: :h2, style: 'color:#000;margin:0',c: r[Title]}]},c.to_s],
29
46
  style: 'float:left;max-width:40em;position:relative;background-color:#fff;border-color:#eee;margin-top:93px;margin-right:.3em;padding-top:0;border-style:dotted;border-width:.3em;border-radius:0 .8em .8em .8em'}
@@ -1,5 +1,5 @@
1
1
  #watch __FILE__
2
- class E
2
+ class R
3
3
 
4
4
  fn 'req/day',->e,r{
5
5
  [303, {'Location'=> e.day.uri + r.q.except('y').qs}, []]}
@@ -51,7 +51,7 @@ class E
51
51
 
52
52
  fn 'view/month',->d,e{
53
53
  [(d.delete :time).do{|month|
54
- {_: :b, c: month.strftime('%B'),style: "color: #{E.cs}"}},
54
+ {_: :b, c: month.strftime('%B'),style: "color: #{R.cs}"}},
55
55
  F['view/t'][d,e,'day','day-terminate']]}
56
56
 
57
57
  fn 'view/day-terminate',->d,e{
@@ -1,4 +1,4 @@
1
- class E
1
+ class R
2
2
 
3
3
  def triplrSourceCode
4
4
  m = mime.split(/\//)[-1].sub(/^x-/,'')
@@ -10,7 +10,7 @@ class E
10
10
  end
11
11
 
12
12
  fn 'view/code',->d,e{[{_: :style, c: 'body{background-color:white;color:black}'},
13
- d.values.map{|r|[r.E.do{|e|[{_: :a,name: e.uri},e.html(e.base,true)]},'<br>',
13
+ d.values.map{|r|[r.R.do{|e|[{_: :a,name: e.uri},e.html(e.base,true)]},'<br>',
14
14
  r[Content]]}]}
15
15
 
16
16
  # ls /usr/share/source-highlight/*.lang | xargs -i basename {} .lang | tr "\n" " "
@@ -1,7 +1,6 @@
1
- class E
1
+ class R
2
2
 
3
3
  FSbase = `pwd`.chomp ; BaseLen = FSbase.size
4
- S = /\._/ # data path-separator
5
4
 
6
5
  W3 = 'http://www.w3.org/'
7
6
  Purl = 'http://purl.org/'
@@ -46,10 +45,13 @@ class E
46
45
  Prefix={
47
46
  "dc" => DC,
48
47
  "foaf" => FOAF,
49
- "rdf" => W3 + "ns/rdf#" ,
48
+ "rdf" => RDFns,
50
49
  "rdfs" => RDFs,
51
50
  "sioc" => SIOC,
51
+ "sioct" => SIOCt,
52
52
  "stat" => Stat,
53
53
  }
54
54
 
55
+ attr_reader :uri
56
+
55
57
  end
@@ -1,19 +1,19 @@
1
1
  #watch __FILE__
2
- class E
2
+ class R
3
3
 
4
4
  # CSV -> tripleStream
5
5
  def triplrCSV d
6
6
  d = @r.q['delim']||d
7
7
  open(node).readlines.map{|l|l.chomp.split(d) rescue []}.do{|lines|
8
8
  lines[0].do{|fields| # ok, we have at least one line..
9
- yield uri+'#', Type, E[CSV+'Table']
9
+ yield uri+'#', Type, R[CSV+'Table']
10
10
  yield uri+'#', CSV+'rowCount', lines.size
11
- yield uri+'#', COGS+'View', E[uri+'?view=csv']
11
+ yield uri+'#', COGS+'View', R[uri+'?view=csv']
12
12
  lines[1..-1].each_with_index{|row,line|
13
13
  row.each_with_index{|field,i|
14
14
  id = uri + '#row:' + line.to_s
15
15
  yield id, fields[i], field
16
- yield id, Type, E[CSV+'Row']
16
+ yield id, Type, R[CSV+'Row']
17
17
  }}}}
18
18
  end
19
19
 
@@ -24,7 +24,7 @@ class E
24
24
  r[Type].do{|t|
25
25
  t.class == Array &&
26
26
  t.map(&:maybeURI).member?(CSV+'Row')})}
27
- # done w/ the type-tag
27
+ # eat the type-tag
28
28
  d.values.map{|r|r.delete Type}
29
29
 
30
30
  [F['view/p'][d,e],
@@ -1,5 +1,5 @@
1
- watch __FILE__
2
- class E
1
+ #watch __FILE__
2
+ class R
3
3
 
4
4
  Prototypes = {
5
5
  SIOCt+'MicroblogPost' => [Content],
@@ -16,7 +16,7 @@ class E
16
16
  fn 'view/create',->g,e{
17
17
  [{_: :style, c: 'a {display:block;font-size:2em}'},{_: :b, c: :type},
18
18
  Prototypes.map{|t,ps|
19
- {_: :a, href: e['REQUEST_PATH']+'?graph=edit&prototype='+(CGI.escape t), c: t.label}}]}
19
+ {_: :a, href: e['REQUEST_PATH']+'?graph=edit&prototype='+(URI.escape t.shorten), c: t.label}}]}
20
20
 
21
21
  # editable triples
22
22
  F['protograph/edit'] = -> e,env,g {
@@ -25,6 +25,7 @@ class E
25
25
  rand.to_s.h}
26
26
 
27
27
  fn 'graph/edit',->e,env,g{
28
+ puts "graph.edit #{e}"
28
29
  e.fromStream g, :triplrDoc} # add fs-sourced triples
29
30
 
30
31
  =begin HTML <form> RDF editor
@@ -35,47 +36,42 @@ class E
35
36
  fn 'view/edit',->g,e{
36
37
 
37
38
  # render a triple
38
- triple = ->s,p,o{
39
- if s && p && o
40
- s = s.E
41
- p = p.E
42
- oE = p.literal o # cast literal to URI
43
- id = s.concatURI(p).concatURI oE # triple identifier
44
- [(case p.uri # more to support here.. http://dev.w3.org/html5/markup/input.html#input
45
- when Content
46
- [{_: :textarea, name: id, c: o, rows: 16, cols: 80},
47
- '<br>',o]
48
- when Date
49
- {_: :input, name: id, type: :datetime, value: o.empty? ? Time.now.iso8601 : o}
50
- else
51
- {_: :input, name: id, value: o, size: 54}
52
- end
53
- ),"<br>\n"]
54
- end}
55
-
39
+ triple = ->s,p,o{ # http://dev.w3.org/html5/markup/input.html#input
40
+ spo = o && s.R.predicatePath(p).objectPath(o)[0].uri
41
+ t = CGI.escape [s,p,spo].to_json
42
+ [(case p.R.uri
43
+ when Content
44
+ [{_: :textarea, name: t, c: o, rows: 16, cols: 80},
45
+ '<br>',o]
46
+ when Date
47
+ {_: :input, name: t, type: :datetime, value: !o || o.empty? && Time.now.iso8601 || o}
48
+ else
49
+ {_: :input, name: t, value: o, size: 54}
50
+ end
51
+ ),"<br>\n"]}
52
+
56
53
  ps = [] # predicates to go editable on
57
- e.q['prototype'].do{|pr|
54
+ e.q['prototype'].do{|pr| pr = pr.expand
58
55
  Prototypes[pr].do{|v|ps.concat v }} # prototype imports
59
56
  e.q['predicate'].do{|p|ps.push p } # explicit predicate
60
57
 
61
- [{_: :style, c: ".abbr {display: none}\ntd {vertical-align:top}"},
58
+ [H.css('/css/html'),
62
59
  {_: :form, name: :editor, method: :POST, action: e['REQUEST_PATH'],
63
60
 
64
61
  c: [{_: :a, class: :edit, c: '+add field',
65
62
  href: e['uri']+'?graph=blank&view=addP', style: 'background-color:#0f0;border-radius:5em;color:#000;padding:.5em'},
66
63
  g.map{|s,r| # subject
67
- uri = s.E.localURL e
68
- {_: :table, style: 'background-color:#eee',
64
+ uri = s.R.localURL e
65
+ {_: :table, class: :html,
69
66
  c: [{_: :tr, c: {_: :td, colspan: 2, c: {_: :a, class: :uri, id: s, c: s, href: uri}}},
70
- {_: :input, type: :hidden, name: s.E.concatURI(Edit.E).concatURI(E['/']), value: e['uri']+'?graph=edit'},
71
67
  r.keys.-([Edit]).concat(ps).uniq.map{|p| # resource + prototype/initialize predicates
72
68
  {_: :tr,
73
- c: [{_: :td, c: {_: :a, title: p, href: p, c: p.abbrURI}}, # property
69
+ c: [{_: :td, class: :key, c: {_: :a, title: p, href: p, c: p.abbrURI}}, # property
74
70
  {_: :td,
75
71
  c: [r[p].do{|o| # objects
76
72
  (o.class == Array ? o : [o]).map{|o| # each object
77
73
  triple[s,p,o]}}, # existing triples
78
- triple[s,p,'']]}]}}]}}, # new triple
74
+ triple[s,p,nil]]}]}}]}}, # new triple
79
75
  {_: :input, type: :submit, value: 'save'}]}]}
80
76
 
81
77
  # select a property to edit