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.
- data/infod.rb +51 -12
- data/infod/{Th/404.rb → 404.rb} +4 -16
- data/infod/500.rb +53 -0
- data/infod/GET.rb +104 -0
- data/infod/HEAD.rb +23 -0
- data/infod/HTTP.rb +105 -0
- data/infod/{Th/PATCH.rb → PATCH.rb} +0 -0
- data/infod/POST.rb +34 -0
- data/infod/audio.rb +30 -0
- data/infod/blog.rb +34 -0
- data/infod/cal.rb +72 -0
- data/infod/{Es/code.rb → code.rb} +7 -4
- data/infod/constants.rb +55 -0
- data/infod/{Es/css.rb → css.rb} +0 -0
- data/infod/{Es/csv.rb → csv.rb} +0 -0
- data/infod/{Es/du.rb → du.rb} +0 -0
- data/infod/edit.rb +73 -0
- data/infod/{H/facets.rb → facets.rb} +20 -11
- data/infod/{Es/feed.rb → feed.rb} +17 -16
- data/infod/{Es/find.rb → find.rb} +2 -3
- data/infod/forum.rb +13 -0
- data/infod/{Es/fs.rb → fs.rb} +5 -2
- data/infod/glob.rb +26 -0
- data/infod/graph.rb +131 -0
- data/infod/{Es/grep.rb → grep.rb} +3 -3
- data/infod/{Es/groonga.rb → groonga.rb} +35 -26
- data/infod/{H/histogram.rb → histogram.rb} +23 -16
- data/infod/html.rb +231 -0
- data/infod/{Es/image.rb → image.rb} +16 -26
- data/infod/{Es/index.rb → index.rb} +44 -49
- data/infod/infod.rb +51 -12
- data/infod/json.rb +38 -0
- data/infod/{Es/kv.rb → kv.rb} +3 -9
- data/infod/{Y.rb → lambda.rb} +18 -1
- data/infod/ls.rb +49 -0
- data/infod/mail.rb +108 -0
- data/infod/{Es/man.rb → man.rb} +3 -15
- data/infod/{H/microblog.rb → microblog.rb} +22 -31
- data/infod/{K.rb → mime.rb} +68 -52
- data/infod/{N.rb → names.rb} +77 -56
- data/infod/page.rb +13 -0
- data/infod/postscript.rb +26 -0
- data/infod/rdf.rb +51 -0
- data/infod/{Rb.rb → ruby.rb} +18 -33
- data/infod/{Es/schema.rb → schema.rb} +23 -8
- data/infod/{Es/search.rb → search.rb} +5 -11
- data/infod/{Es/sh.rb → sh.rb} +0 -0
- data/infod/{Es/text.rb → text.rb} +33 -29
- data/infod/{H/threads.rb → threads.rb} +20 -27
- data/infod/{H/time.rb → time.rb} +14 -34
- data/infod/{H/wiki.rb → wiki.rb} +0 -0
- metadata +53 -64
- data/config.ru +0 -3
- data/infod/Es.rb +0 -31
- data/infod/Es/filter.rb +0 -75
- data/infod/Es/glob.rb +0 -22
- data/infod/Es/html.rb +0 -271
- data/infod/Es/in.rb +0 -68
- data/infod/Es/json.rb +0 -68
- data/infod/Es/ls.rb +0 -58
- data/infod/Es/mail.rb +0 -87
- data/infod/Es/mime.rb +0 -59
- data/infod/Es/out.rb +0 -52
- data/infod/Es/pager.rb +0 -34
- data/infod/Es/pdf.rb +0 -19
- data/infod/Es/rdf.rb +0 -35
- data/infod/H.rb +0 -15
- data/infod/H/audio.rb +0 -19
- data/infod/H/blog.rb +0 -15
- data/infod/H/cal.rb +0 -81
- data/infod/H/edit.rb +0 -88
- data/infod/H/forum.rb +0 -4
- data/infod/H/hf.rb +0 -114
- data/infod/H/mail.rb +0 -92
- data/infod/H/who.rb +0 -30
- data/infod/Th.rb +0 -36
- data/infod/Th/500.rb +0 -41
- data/infod/Th/GET.rb +0 -62
- data/infod/Th/HEAD.rb +0 -5
- data/infod/Th/POST.rb +0 -39
- data/infod/Th/perf.rb +0 -37
- data/infod/Th/uid.rb +0 -24
- data/infod/Th/util.rb +0 -89
data/infod/H/who.rb
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
#watch __FILE__
|
2
|
-
class E
|
3
|
-
|
4
|
-
fn '/whois/GET',->e,r{
|
5
|
-
[302,{Location: '/' + ( r.q['p'].match(/to$/) ? 'to' : 'from' ) + '/' + (URI.escape r.q['q'])},[]]
|
6
|
-
}
|
7
|
-
|
8
|
-
fn '/to/GET',->e,r{
|
9
|
-
name = e.pathSegment.uri.sub('/to/','/').tail
|
10
|
-
if !name || name.empty?
|
11
|
-
false
|
12
|
-
else
|
13
|
-
H({style: 'text-align: center',
|
14
|
-
c: [To.E.rangeP.map(&:uri).grep(/#{name}/).map{|n|
|
15
|
-
{_: :a,href: n.E.url+'?set=indexPO&p=sioc:addressed_to&view=page&v', c: n}},
|
16
|
-
{_: :style, c: "a {display:block;text-decoration:none}"}]}).hR
|
17
|
-
end}
|
18
|
-
|
19
|
-
fn '/from/GET',->e,r{
|
20
|
-
name = e.pathSegment.uri.sub('/from/','/').tail
|
21
|
-
if !name || name.empty?
|
22
|
-
false
|
23
|
-
else
|
24
|
-
H({style: 'text-align: center',
|
25
|
-
c: [Creator.E.rangeP(1e4).map(&:uri).grep(/#{name}/).map{|n|
|
26
|
-
{_: :a,href: n.E.url+'?set=indexPO&p=sioc:has_creator&view=page&v', c: n}},
|
27
|
-
{_: :style, c: "a {display:block;text-decoration:none}"}]}).hR
|
28
|
-
end}
|
29
|
-
|
30
|
-
end
|
data/infod/Th.rb
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
#watch __FILE__
|
2
|
-
require 'rack'
|
3
|
-
%w{GET HEAD POST PATCH perf uid util 404 500}.map{|i|require_relative 'Th/' + i}
|
4
|
-
|
5
|
-
class E
|
6
|
-
|
7
|
-
def E.call e
|
8
|
-
dev
|
9
|
-
e.extend Th
|
10
|
-
e['HTTP_X_FORWARDED_HOST'].do{|h| e['SERVER_NAME'] = h }
|
11
|
-
p = e['REQUEST_PATH'].force_encoding 'UTF-8'
|
12
|
-
|
13
|
-
uri = CGI.unescape(if (p.index Prefix) == 0
|
14
|
-
p[Prefix.size..-1]
|
15
|
-
else
|
16
|
-
'http://' + e['SERVER_NAME'] + (p.gsub '+','%2B')
|
17
|
-
end).E.env e
|
18
|
-
|
19
|
-
if (uri.node.expand_path.to_s.index FSbase) == 0
|
20
|
-
e['uri'] = uri.uri
|
21
|
-
# response
|
22
|
-
r = nil # request method
|
23
|
-
b = Benchmark.measure{ r = uri.send e.fn }
|
24
|
-
F['log'][r[0],e,b.real]
|
25
|
-
r
|
26
|
-
else
|
27
|
-
[403,{},['Forbidden']]
|
28
|
-
end
|
29
|
-
|
30
|
-
rescue Exception => x
|
31
|
-
$stderr.puts 500, e['REQUEST_URI'] ,x.message,x.backtrace
|
32
|
-
F['log'][500,e]
|
33
|
-
F['E500'][x,@r]
|
34
|
-
end
|
35
|
-
|
36
|
-
end
|
data/infod/Th/500.rb
DELETED
@@ -1,41 +0,0 @@
|
|
1
|
-
class E
|
2
|
-
|
3
|
-
fn '/css/500.css/GET',->e,r{
|
4
|
-
[200,{'Content-Type'=>'text/css'},["
|
5
|
-
body {margin:0; font-family: sans-serif; background-color:#fff; color:#000}
|
6
|
-
h1 {padding:.2em; background-color:#f00; color:#fff; margin:0}
|
7
|
-
div {display:inline}
|
8
|
-
table {border-spacing:0;margin:0}
|
9
|
-
b {background-color:#eee;color:#500;padding:.1em .3em .1em .3em}
|
10
|
-
.frag {font-weight:bold; color:#000; background-color:#{E.cs}}
|
11
|
-
td.space {background-color:#ddd}
|
12
|
-
td.message {background-color:#009;color:#fff}
|
13
|
-
td.path {text-align:right}
|
14
|
-
td.index {text-align:right;border-color:#000;border-width:0 0 .1em 0;border-style:dotted;background-color:#ddd;color:#000}
|
15
|
-
td.context {border-color:#ddd;border-width:0 0 .1em 0;border-style:dotted;padding:.15em}"]]}
|
16
|
-
|
17
|
-
F['/E/error/GET'] = ->e,r{1/0}
|
18
|
-
|
19
|
-
fn 'E500',->x,r{
|
20
|
-
[500,{'Content-Type'=>'text/html'},
|
21
|
-
[H[{_: :html,
|
22
|
-
c: [{_: :head,
|
23
|
-
c: [{_: :title, c: 500},(H.css '/css/500')]},
|
24
|
-
{_: :body,
|
25
|
-
c: [{_: :h1, c: 500},
|
26
|
-
{_: :table,
|
27
|
-
c: [{_: :tr,
|
28
|
-
c: [{_: :td, c: {_: :b, c: x.class}},
|
29
|
-
{_: :td, class: :space},
|
30
|
-
{_: :td, class: :message, c: x.message.hrefs}
|
31
|
-
]},
|
32
|
-
x.backtrace.map{|p|
|
33
|
-
p = p.split /:/, 3
|
34
|
-
{_: :tr,
|
35
|
-
c: [{_: :td, class: :path, c: F['abbrURI'][p[0]]},
|
36
|
-
{_: :td, class: :index, c: p[1]},
|
37
|
-
{_: :td, class: :context, c: (p[2]||'').hrefs}].cr}}.cr]}]}]}]]]}
|
38
|
-
|
39
|
-
F['/500/GET'] = ->e,r{H([Errors.sort_by{|u,r|r[:time]}.reverse.html,H.css('/css/500')]).hR}
|
40
|
-
|
41
|
-
end
|
data/infod/Th/GET.rb
DELETED
@@ -1,62 +0,0 @@
|
|
1
|
-
class E
|
2
|
-
|
3
|
-
def GET
|
4
|
-
# bespoke handler ||
|
5
|
-
# raw file ||
|
6
|
-
# resource
|
7
|
-
if reqFn = F['req/'+@r.q['y']]
|
8
|
-
reqFn[self,@r]
|
9
|
-
elsif file = [self,pathSegment].compact.find(&:f)
|
10
|
-
a = @r.accept.values.flatten
|
11
|
-
accepted = a.empty? || (a.member? file.mimeP) || (a.member? '*/*')
|
12
|
-
(@r.q.has_any_key(%w{format view}) ||
|
13
|
-
MIMEcook[file.mimeP] || !accepted) ? resource : (file.env @r).getFile
|
14
|
-
else
|
15
|
-
resource
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def getFile
|
20
|
-
@r['ETag'] = [m,size].h
|
21
|
-
maybeSend mimeP,->{self},:link
|
22
|
-
end
|
23
|
-
|
24
|
-
def resource
|
25
|
-
# bubble up site then global tree until handled (false return-value to pass)
|
26
|
-
pathSegment.do{|path|
|
27
|
-
lambdas = path.cascade.map{|p| p.uri.t + 'GET' }
|
28
|
-
['http://'+@r['SERVER_NAME'],""].map{|h| lambdas.map{|p|
|
29
|
-
F[h + p].do{|fn| fn[self,@r].do{|r| return r}}}}}
|
30
|
-
|
31
|
-
# default handler
|
32
|
-
response
|
33
|
-
end
|
34
|
-
|
35
|
-
def send?
|
36
|
-
!((m=@r['HTTP_IF_NONE_MATCH']) && m.strip.split(/\s*,\s*/).include?(@r['ETag']))
|
37
|
-
end
|
38
|
-
|
39
|
-
def maybeSend m,b,lH=false
|
40
|
-
# agent need this version?
|
41
|
-
send? ?
|
42
|
-
# continue
|
43
|
-
b[].do{|b|
|
44
|
-
# response metadata
|
45
|
-
h = {'Content-Type'=> m,
|
46
|
-
'ETag'=> @r['ETag']}
|
47
|
-
h.update({'Cache-Control' => 'no-transform'}) if m.match /^(audio|image|video)/
|
48
|
-
h.update({'Link' => '<' + @r['uri'] + '?view=base>; rel=meta'}) if lH
|
49
|
-
|
50
|
-
b.class == E ? (Nginx ? # nginx enabled
|
51
|
-
[200,h.update({'X-Accel-Redirect' => '/fs' + b.path}),[]] : # Nginx file-handler
|
52
|
-
Apache ? # Apache enabled
|
53
|
-
[200,h.update({'X-Sendfile' => b.d}),[]] : # Apache file-handler
|
54
|
-
(r = Rack::File.new nil # Rack file-handler
|
55
|
-
r.instance_variable_set '@path',b.d
|
56
|
-
r.serving(@r).do{|s,m,b|[s,m.update(h),b]})
|
57
|
-
) :
|
58
|
-
[200, h, b]} : # normal (unaccelerated) response
|
59
|
-
[304,{},[]] # client has response version
|
60
|
-
end
|
61
|
-
|
62
|
-
end
|
data/infod/Th/HEAD.rb
DELETED
data/infod/Th/POST.rb
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
watch __FILE__
|
2
|
-
class E
|
3
|
-
|
4
|
-
def POST
|
5
|
-
r = Rack::Request.new @r
|
6
|
-
p = nil
|
7
|
-
# each triple
|
8
|
-
r.params.map{|k,v|
|
9
|
-
|
10
|
-
# path-format triple
|
11
|
-
sP,pP,oP = (CGI.unescape k).split S
|
12
|
-
|
13
|
-
# original triple
|
14
|
-
s,p,o = [sP,pP,oP].map &:unpath
|
15
|
-
|
16
|
-
p = p.uri[0..-2].E if p.uri[-1] == '/'
|
17
|
-
|
18
|
-
# object-delta URIs
|
19
|
-
vU = E.literal v
|
20
|
-
oU = oP.E
|
21
|
-
|
22
|
-
# change detected
|
23
|
-
unless oU.uri == vU.uri
|
24
|
-
# edit triple
|
25
|
-
s[p,o,v]
|
26
|
-
end
|
27
|
-
|
28
|
-
# snapshot current resource state
|
29
|
-
|
30
|
-
}
|
31
|
-
|
32
|
-
# parameters for editor
|
33
|
-
@r.q.update({'view' => 'editPO',
|
34
|
-
'graph' => 'editable',
|
35
|
-
'p' => p.uri})
|
36
|
-
self.GET
|
37
|
-
end
|
38
|
-
|
39
|
-
end
|
data/infod/Th/perf.rb
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
#watch __FILE__
|
2
|
-
require 'benchmark'
|
3
|
-
|
4
|
-
class E
|
5
|
-
|
6
|
-
Slow ||= {}
|
7
|
-
Errors ||= {}
|
8
|
-
F['log']=->c,e,x=nil{ # response code, environment, extra stuff
|
9
|
-
uri = ['http://', e['SERVER_NAME'], e['REQUEST_URI']].join
|
10
|
-
if 500 == c
|
11
|
-
Errors[uri] ||= {}
|
12
|
-
Errors[uri][:time] = Time.now
|
13
|
-
end
|
14
|
-
if x && x.class==Float && x > 1
|
15
|
-
s = Slow[uri] ||= {}
|
16
|
-
s[:time] ||= 0
|
17
|
-
s[:time] += x
|
18
|
-
s[:last] = Time.now
|
19
|
-
if Slow.size > 10e3
|
20
|
-
Slow = {}
|
21
|
-
end
|
22
|
-
end
|
23
|
-
$stdout.puts [e.fn,c,uri,e['HTTP_USER_AGENT'],e['HTTP_REFERER'],x].join ' '}
|
24
|
-
|
25
|
-
F['/health/GET'] = ->e,r{
|
26
|
-
e.pathSegment.uri.match(/^(\/|\/health)$/) &&
|
27
|
-
(H [{_: :h1,
|
28
|
-
c: {_: :a, href: '/', style: "background-color:"+E.cs, c: '/'}},
|
29
|
-
{c: [{_: :b, c: r['SERVER_NAME']},' storage ',`df --output=pcent /|tail -n 1`]},
|
30
|
-
{_: :a, href: '/slow', c: 'slow queries'},
|
31
|
-
{_: :A, href: '/500', c: 'broken requests'},
|
32
|
-
H.css('/css/health')
|
33
|
-
]).hR}
|
34
|
-
|
35
|
-
F['/slow/GET'] = ->e,r{H([Slow.sort_by{|u,r|r[:time]}.reverse.html,H.css('/css/500')]).hR}
|
36
|
-
|
37
|
-
end
|
data/infod/Th/uid.rb
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
#watch __FILE__
|
2
|
-
|
3
|
-
module Th
|
4
|
-
FingerprintKeys = %w{
|
5
|
-
HTTP_ACCEPT
|
6
|
-
HTTP_ACCEPT_CHARSET
|
7
|
-
HTTP_ACCEPT_LANGUAGE
|
8
|
-
HTTP_ACCEPT_ENCODING
|
9
|
-
HTTP_USER_AGENT
|
10
|
-
HTTP_ORIGIN_ADDR
|
11
|
-
REMOTE_ADDR
|
12
|
-
}
|
13
|
-
|
14
|
-
def uid
|
15
|
-
('/u/'+FingerprintKeys.map{|i|self[i]}.h.dive).E
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
class E
|
20
|
-
|
21
|
-
fn '/whoami/GET',->e,r{
|
22
|
-
[302,{Location: '/@'+r.uid.uri},[]]}
|
23
|
-
|
24
|
-
end
|
data/infod/Th/util.rb
DELETED
@@ -1,89 +0,0 @@
|
|
1
|
-
class String
|
2
|
-
# parse query-string
|
3
|
-
def qp
|
4
|
-
d={}
|
5
|
-
split(/&/).map{|e|
|
6
|
-
k,v=e.split(/=/,2).map{|x|
|
7
|
-
CGI.unescape x}
|
8
|
-
d[k]=v}
|
9
|
-
d
|
10
|
-
end
|
11
|
-
# HTML response of string body
|
12
|
-
def hR
|
13
|
-
[200,{'Content-Type'=>'text/html; charset=utf-8'},
|
14
|
-
[self]]
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
module Th
|
19
|
-
|
20
|
-
# unparsed query-string
|
21
|
-
def qs
|
22
|
-
(['GET','HEAD'].member? fn) ? self['QUERY_STRING'] : self['rack.input'].read
|
23
|
-
end
|
24
|
-
|
25
|
-
# memoize query
|
26
|
-
def q
|
27
|
-
@q ||= (qs||'').qp.do{|q|
|
28
|
-
(q['?']).do{|d|
|
29
|
-
E::F['?'][d].do{|g| # expand aliases
|
30
|
-
g.merge q
|
31
|
-
} || q } || q}
|
32
|
-
end
|
33
|
-
|
34
|
-
# Accept header
|
35
|
-
def accept_ k=''
|
36
|
-
d={}
|
37
|
-
self['HTTP_ACCEPT'+k].do{|k|
|
38
|
-
k.split(/,/).map{|e|
|
39
|
-
f,q=e.split(/;/)
|
40
|
-
i=q&&q.split(/=/)[1].to_f||1
|
41
|
-
d[i]||=[]
|
42
|
-
d[i].push f}}
|
43
|
-
d
|
44
|
-
end
|
45
|
-
|
46
|
-
def format
|
47
|
-
@format ||= conneg
|
48
|
-
end
|
49
|
-
|
50
|
-
def conneg
|
51
|
-
# format in querystring
|
52
|
-
return q['format'] if q['format'] && E::F[E::Render+q['format']]
|
53
|
-
# format in Accept header
|
54
|
-
accept.sort.reverse.map{|p|p[1].map{|mime|
|
55
|
-
return mime if E::F[E::Render+mime]}}
|
56
|
-
# default
|
57
|
-
'text/html'
|
58
|
-
end
|
59
|
-
|
60
|
-
def accept; @accept ||= accept_ end
|
61
|
-
|
62
|
-
def fn
|
63
|
-
self['REQUEST_METHOD']
|
64
|
-
end
|
65
|
-
|
66
|
-
end
|
67
|
-
|
68
|
-
class Hash
|
69
|
-
|
70
|
-
def qs
|
71
|
-
'?'+map{|k,v|k.to_s+'='+(v ? (CGI.escape [*v][0].to_s) : '')}.intersperse("&").join('')
|
72
|
-
end
|
73
|
-
|
74
|
-
def env r # attach environment variable
|
75
|
-
@r = r
|
76
|
-
self
|
77
|
-
end
|
78
|
-
|
79
|
-
end
|
80
|
-
|
81
|
-
class E
|
82
|
-
|
83
|
-
# request environment
|
84
|
-
def env r=nil
|
85
|
-
r ? (@r = r
|
86
|
-
self) : @r
|
87
|
-
end
|
88
|
-
|
89
|
-
end
|