infod 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. data/infod.rb +2 -3
  2. data/infod/Es.rb +31 -67
  3. data/infod/{W/source.rb → Es/code.rb} +6 -10
  4. data/infod/Es/css.rb +21 -0
  5. data/infod/{W → Es}/csv.rb +0 -0
  6. data/infod/Es/du.rb +16 -0
  7. data/infod/{W → Es}/feed.rb +13 -11
  8. data/infod/Es/filter.rb +75 -0
  9. data/infod/Es/find.rb +20 -0
  10. data/infod/Es/fs.rb +145 -136
  11. data/infod/Es/glob.rb +22 -0
  12. data/infod/Es/grep.rb +61 -0
  13. data/infod/Es/groonga.rb +47 -56
  14. data/infod/Es/html.rb +271 -0
  15. data/infod/Es/image.rb +114 -0
  16. data/infod/Es/in.rb +68 -0
  17. data/infod/Es/index.rb +183 -0
  18. data/infod/{W → Es}/json.rb +28 -4
  19. data/infod/Es/kv.rb +60 -0
  20. data/infod/Es/ls.rb +58 -0
  21. data/infod/Es/mail.rb +87 -0
  22. data/infod/Es/man.rb +112 -0
  23. data/infod/Es/mime.rb +59 -0
  24. data/infod/Es/out.rb +52 -0
  25. data/infod/{W/page.rb → Es/pager.rb} +7 -3
  26. data/infod/Es/pdf.rb +19 -0
  27. data/infod/Es/rdf.rb +35 -0
  28. data/infod/Es/schema.rb +99 -0
  29. data/infod/Es/search.rb +24 -0
  30. data/infod/Es/sh.rb +21 -0
  31. data/infod/{W → Es}/text.rb +26 -14
  32. data/infod/H.rb +15 -29
  33. data/infod/H/audio.rb +19 -0
  34. data/infod/H/blog.rb +15 -0
  35. data/infod/{W → H}/cal.rb +2 -31
  36. data/infod/H/edit.rb +88 -0
  37. data/infod/{W/examine/examine.rb → H/facets.rb} +17 -17
  38. data/infod/{W → H}/forum.rb +1 -0
  39. data/infod/{W/examine/sw.rb → H/hf.rb} +12 -12
  40. data/infod/H/histogram.rb +78 -0
  41. data/infod/H/mail.rb +92 -0
  42. data/infod/{W/chat.rb → H/microblog.rb} +21 -16
  43. data/infod/H/threads.rb +77 -0
  44. data/infod/H/time.rb +131 -0
  45. data/infod/H/who.rb +30 -0
  46. data/infod/{W → H}/wiki.rb +0 -0
  47. data/infod/K.rb +28 -60
  48. data/infod/N.rb +151 -74
  49. data/infod/Rb.rb +3 -3
  50. data/infod/Th.rb +27 -101
  51. data/infod/Th/404.rb +29 -36
  52. data/infod/Th/500.rb +36 -5
  53. data/infod/Th/GET.rb +48 -118
  54. data/infod/Th/POST.rb +31 -11
  55. data/infod/Th/perf.rb +37 -0
  56. data/infod/Th/util.rb +89 -0
  57. data/infod/Y.rb +24 -7
  58. data/infod/infod.rb +2 -3
  59. metadata +92 -64
  60. data/infod/Es/redis.rb +0 -3
  61. data/infod/Es/sqlite.rb +0 -3
  62. data/infod/Th/local.rb +0 -22
  63. data/infod/W.rb +0 -34
  64. data/infod/W/audio.rb +0 -56
  65. data/infod/W/blog.rb +0 -3
  66. data/infod/W/color.rb +0 -28
  67. data/infod/W/core.rb +0 -77
  68. data/infod/W/css.rb +0 -24
  69. data/infod/W/du.rb +0 -35
  70. data/infod/W/edit.rb +0 -8
  71. data/infod/W/examine/exhibit.rb +0 -34
  72. data/infod/W/examine/hist.rb +0 -55
  73. data/infod/W/examine/history.rb +0 -19
  74. data/infod/W/examine/normal.rb +0 -31
  75. data/infod/W/examine/protovis.rb +0 -30
  76. data/infod/W/examine/time/graph.rb +0 -86
  77. data/infod/W/examine/time/line.rb +0 -24
  78. data/infod/W/find.rb +0 -24
  79. data/infod/W/grep.rb +0 -27
  80. data/infod/W/html.rb +0 -143
  81. data/infod/W/image.rb +0 -61
  82. data/infod/W/kv.rb +0 -66
  83. data/infod/W/ls.rb +0 -50
  84. data/infod/W/mail.rb +0 -248
  85. data/infod/W/pdf.rb +0 -16
  86. data/infod/W/post.rb +0 -9
  87. data/infod/W/rdf.rb +0 -32
  88. data/infod/W/schema.rb +0 -172
  89. data/infod/W/search.rb +0 -33
  90. data/infod/W/shell.rb +0 -30
  91. data/infod/W/table.rb +0 -87
  92. data/infod/W/tree.rb +0 -26
  93. data/infod/W/vfs.rb +0 -175
data/infod/W/mail.rb DELETED
@@ -1,248 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- #watch __FILE__
3
-
4
- class E
5
-
6
- # qs alias section
7
- F["?"] ||= {}
8
- F["?"].update({
9
- 'thread' =>{'graph'=>'thread',
10
- 'sort' => 'dc:date',
11
- 'reverse' => nil,
12
- 'view' => 'multi',
13
- 'views' => 'timegraph,mail',
14
- 'arc' => '/parent',
15
- 'label' => 'sioc:name'},
16
- 'ann' =>{'view'=>'threads',
17
- 'matchP' => 'dc:title',
18
- 'match' => /[^a-zA-Z][Aa][Nn][nN]([oO][uU]|[^a-zA-Z])/}})
19
-
20
- def triplrMail; require 'tmail'
21
-
22
- # read message
23
- i = -> i {E i[1..-2]} # Message-ID -> E
24
- (TMail::Mail.load node).do{|m| # parse
25
- d = m.message_id; return unless d # parse successful?
26
- e = i[d] # Message resource
27
- e.e || ( # Message-ID locatable?
28
-
29
- # index previously unseen mail
30
- ln e # create message-id path
31
- %w{in_reply_to references}.map{|p| # reference arcs
32
- m.send(p).do{|o| o.map{|o| # lookup references
33
- e.index SIOC+'reply_of', i[o]}}} # index references
34
- e.ln '/' + m.date.iso8601[0..12].gsub(/[^\d]/,'/') + '/' + e.uri # date/hour index tree
35
- self.index Creator, m.from[0].E # index From
36
- self.index To, m.to[0].E ) # index To
37
-
38
- # yield triples
39
- yield e.uri, Type, E[SIOCt+'MailMessage']
40
- yield e.uri, Date, m.date.iso8601 if m.date
41
- yield e.uri, Content, m.decentBody
42
- [[:subject,Title],
43
- [:to,To,true],
44
- [:cc,To,true],
45
- [:bcc,To,true],
46
- [:friendly_from,SIOC+'name'],
47
- [:from,Creator,true],
48
- [:reply_to,'/mail/reply_to',true],
49
- [:in_reply_to,'/parent',true,true],
50
- [:in_reply_to,SIOC+'reply_of',true,true],
51
- [:references,SIOC+'reply_of',true,true],
52
- ].each{|a| m.send(a[0]).do{|o| [*o].map{|o|
53
- yield e.uri,a[1], # skip empty String values
54
- (a[2] ? (a[3] ? i[o] : o.E) : o.to_utf8) unless o.match(/\A[, \n]*\Z/)}}}}
55
-
56
- rescue Exception => e
57
- puts [:mail,uri,e].join(' ')
58
- end
59
-
60
- fn 'graph/thread',->d,_,m{d.walk SIOC+'reply_of',m}
61
-
62
- # overview of a message set
63
- fn 'view/threads',->d,env{
64
-
65
- # occurrence-count statistics
66
- g = {}
67
- d.map{|_,m|
68
- m[To].map{|t|
69
- g[t.uri]||=0
70
- g[t.uri]=g[t.uri].succ}}
71
-
72
- # CSS
73
- [(H.css '/css/mail'),
74
-
75
- ([{_: :a, href: '/@'+env.q['p']+'?set=indexP&view=page&v=linkPO&c=12', c: env.q['p']},
76
- {_: :a, href: '/m?y=day', c: ' :: '},
77
- {_: :a, href: E[env['uri']].url+'?set=indexPO&view=page&v=threads&c=32&p='+env.q['p'], c: env['uri']}
78
- ] if env.q['set']=='indexPO'),
79
-
80
- '<table>',
81
-
82
- # subgroup by title
83
- d.values.group_by{|r|[*r[Title]][0].sub(/^[rR][eE][^A-Za-z]./,'')}.
84
-
85
- # group by recipient
86
- group_by{|r,k|
87
-
88
- # show most-popular first
89
- k[0].do{|k|
90
- k[To].do{|o|o.sort_by{|t|g[t.uri]}.reverse.head.uri}}}.
91
-
92
- # display
93
- map{|e|
94
- # recipient-group color
95
- c = '#%06x' % rand(16777216)
96
- ['<tr><td class=subject>',
97
-
98
- # show most-popular groups first
99
- e[1].sort_by{|m|m[1].size}.reverse.map{|t|
100
-
101
- # link to thread
102
- [{_: :a, property: Title, :class => 'thread', style: "border-color:#{c}", href: t[1][0].url+'??=thread',
103
- c: t[0].to_s.gsub(/[<>]/,'_').gsub(/\[([a-z\-A-Z0-9]+)\]/,'<span class=g>\1</span>')},
104
-
105
- # link to individual messages
106
- (t[1].size > 1 &&
107
- ['<br>', t[1].map{|s|
108
-
109
- # author name and RDFa
110
- [{_: :a, property: Creator, href: s.url+'??=thread#'+s.uri, :class => 'sender', style: 'background-color:'+c,
111
- c: s[SIOC+'name'][0].split(/\W/,2)[0]},' ']}]),'<br>']},'</td>',
112
-
113
- # recipient group, Mailing List
114
- {_: :td, class: :group, property: To,
115
- c: {_: :a, :class => :to, style: 'background-color:'+c, c: e[0] && e[0].split(/@/)[0],
116
- href: e[0] && e[0].E.url+'?set=indexPO&p=sioc:addressed_to&view=page&v=threads'}},
117
-
118
- '</tr>']},'</table>',
119
-
120
- # link to show full content of entire message-set
121
- {_: :a, id: :down, c: '&darr;',href: env['REQUEST_PATH']+env.q.merge({'view'=>'page','views'=>'timegraph,mail','v'=>'multi'}).qs}]}
122
-
123
-
124
- # show a set of messages
125
- fn 'view/mail',->d,e{
126
- title = nil
127
-
128
- # JS/CSS dependencies
129
- [(H.once e,'mail.js',
130
- (H.css '/css/mail'),
131
- (H.js '/js/mail'),
132
- (H.once e,:mu,(H.js '/js/mu')),
133
-
134
- # up to set-overview
135
- ({_: :a, id: :up, href: e['REQUEST_PATH'] + e.q.merge({'view' => 'page', 'v' => 'threads'}).qs, c: '&uarr;'} if d.keys.size > 2),
136
-
137
- # collapse/expand quoted content
138
- {id: :showQuote, c: :quote, show: :true},{_: :style, id: :quote}),
139
-
140
- # each message
141
- d.values.map{|m|
142
-
143
- # content available?
144
- [m.class == Hash && (m.has_key? E::SIOC+'content') &&
145
-
146
- {:class => :mail,
147
-
148
- c: [# link to self
149
- {_: :a, name: m.uri, href: m.url, rel: :permalink, title: :link, c: ' '},
150
-
151
- # To:, From: index search links
152
- [['sioc:has_creator',Creator],['sioc:addressed_to',To]].map{|a|
153
- m[a[1]].do{|m|
154
- m.map{|f| f.respond_to?(:uri) &&
155
- {_: :a, property: a[0], href: f.url+'?set=indexPO&p='+a[0]+'&view=page&views=timegraph,mail&v=multi&c=8', c: f.uri}}}},
156
-
157
- # mailto URI with embedded reply metadata
158
- (m['/mail/reply_to']||m[Creator]).do{|r| r[0] && r[0].respond_to?(:uri) &&
159
- {_: :a, title: :reply, c: 'r',
160
- href: "mailto:#{r[0].uri}?References=<#{m.uri}>&In-Reply-To=<#{m.uri}>&Subject=#{m[Title].join}"}},'<br clear=all>',
161
-
162
- # content
163
- {_: :pre,
164
- c: m[Content].map{|b|
165
-
166
- # line count
167
- i = 0
168
-
169
- # HTML message content
170
- b.class==String && b.
171
-
172
- # erase empty quoted lines
173
- gsub(/^\s*(&gt;)(&gt;|\s)*\n/,"").
174
-
175
- # each line
176
- lines.to_a.map{|l|
177
-
178
- # line identifier
179
- f = m.uri + ':' + (i+=1).to_s
180
-
181
- # wrapper
182
- {_: :span,
183
-
184
- # is line quoted?
185
- class: ((l.match /(^\s*(&gt;|On[^\n]+(said|wrote))[^\n]*)\n/) ? 'q' : 'u'), c:
186
-
187
- # id
188
- [{_: :a, id: f},
189
-
190
- # line
191
- l.chomp,
192
-
193
- # link
194
- (l.size > 64 &&
195
- {_: :a, class: :line, href: '#'+f,c: '↵'}),
196
-
197
- "\n" ]}}}}, # collate lines
198
-
199
- # title
200
- m[Title].do{|t|
201
- # only show if changed from previous
202
- title != t[0] && (
203
- title = t[0] # update title
204
- [{:class => :title, c: t.html, _: :a, href: m.url+'??=thread#'+m.uri, style: "color: #{E.c}"},
205
- '<br clear=all>'])}]}]}]}
206
-
207
- # set a default view for MIME and SIOC types
208
- [MIMEtype+'message/rfc822',
209
- SIOCt+'MailMessage'].
210
- map{|m| F['view/'+m] = F['view/mail'] }
211
-
212
- end
213
-
214
- module TMail
215
- class Mail
216
- def unicode_body
217
- unquoted_body.to_utf8
218
- end
219
- def decentBody
220
- unHTML=->t{t.split(/<body[^>]*>/)[-1].split(/<\/body>/)[0]}
221
- if multipart?
222
- parts.collect{ |part|
223
- c = part["content-type"]
224
- if part.multipart?
225
- part.decentBody
226
- elsif header.nil?
227
- ""
228
- elsif !attachment?(part) && c.sub_type != 'html'
229
- part.unicode_body.hrefs(true)
230
- else
231
- (c["name"]||'attach').do{|a|
232
- message_id ? (message_id[1..-2]+'/'+a).E.do{|i|
233
- i.w part.body if !i.e
234
- '<a href='+i.url+'>'+(part.main_type=='image' ? '<img src="'+i.url+'">' : a)+"</a><br>\n"
235
- } : ""};end
236
- }.join
237
-
238
- else
239
- unicode_body.do{|b|content_type&&content_type.match(/html/) ? unHTML.(b) : b.hrefs(true)}
240
- end
241
- rescue
242
- ''
243
- end
244
- end
245
- end
246
-
247
- # TMail calls this nonexistent method on strings
248
- class String; def is_binary_data?; true; end; end
data/infod/W/pdf.rb DELETED
@@ -1,16 +0,0 @@
1
- class E
2
-
3
- F["?"]||={}
4
- F["?"].update({'pdf'=>
5
- {'filter'=>'p',
6
- 'p'=>'uri,Author,Title,Producer,dc:date,stat:size',
7
- 'sort'=>'Producer',
8
- 'view'=>'tab'
9
- }})
10
-
11
- def triplrPDF &f
12
- yield uri,Content,`pdftotext #{sh}; cat #{docBase.a('.txt').sh}`
13
- dateNorm :triplrStdOut,'pdfinfo', &f
14
- end
15
-
16
- end
data/infod/W/post.rb DELETED
@@ -1,9 +0,0 @@
1
- #watch __FILE__
2
- class E
3
-
4
- F['view/'+SIOC+'Post']=->g,r{
5
- g.map{|u,r|
6
- r[Content].do{|c|
7
- [r.html]}}}
8
-
9
- end
data/infod/W/rdf.rb DELETED
@@ -1,32 +0,0 @@
1
- class E
2
-
3
- def self.requireRDF; %w{n3 rdfa rdfxml turtle}.map{|r|require 'rdf/'+r}; require 'json/ld' end
4
-
5
- def self.renderRDF d,f=:ntriples; E.requireRDF
6
- RDF::Writer.for(f).buffer{|w|
7
- d.values.each{|r|
8
- r.triples{|s,p,o|
9
- # puts :s,s,:p,p,:o,o.class,o
10
- w << RDF::Statement.new(RDF::URI(s),RDF::URI(p),
11
- (o.class==Hash||o.class==E) ?
12
- RDF::URI(o.uri) :
13
- RDF::Literal(o))}}}
14
- rescue Exception => e
15
- puts [:RDF,d.keys[0..8],f,e].join ' '
16
- end
17
-
18
- def triplrRDFformats t=nil
19
- E.requireRDF
20
- (t == :rdfa ? RDF::RDFa : RDF)::Reader.
21
- open(e ? d : uri, :format => t){|r|
22
- r.each_triple{|s,p,o|
23
- yield s.to_s, p.to_s,
24
- ((o.class==RDF::Node || o.class==RDF::URI) ? o.to_s.E :
25
- o.value.do{|v|
26
- v.class == String ? v.to_utf8 : v})}}
27
- self
28
- rescue Exception => e
29
- puts [:RDF,uri,e].join ' '
30
- end
31
-
32
- end
data/infod/W/schema.rb DELETED
@@ -1,172 +0,0 @@
1
- #watch __FILE__
2
- class E
3
-
4
- # install schema-cache
5
- def E.schemaCache
6
- E.schemaDocs.map &:schemaCache
7
- end
8
- def E.schemaUncache
9
- E.schemaDocs.map &:schemaUncache
10
- end
11
-
12
- def schemaCache
13
- schemaCacheDoc
14
- schemaIndexDoc
15
- end
16
- def schemaUncache
17
- schemaUnindexDoc
18
- schemaUnlinkSlashURIs
19
- schemaUncacheDoc
20
- end
21
-
22
- # cache schema docs
23
- def schemaCacheDoc
24
- if ttl.e || ef.e # already cached?
25
- print "c "
26
- else
27
- ttl.w(`rapper -o turtle #{uri}`) # write turtle
28
- end
29
- end
30
-
31
- def schemaUncacheDoc
32
- ef.deleteNode # remove JSON
33
- ttl.deleteNode # remove Turtle
34
- end
35
-
36
- # index schema docs
37
- def schemaIndexDoc
38
- c = E.schemaStatistics
39
- if (nt.e || # skip already-processed docs
40
- ttl.do{|d|d.e && d.size > 256e3}) # skip huge dbpedia/wordnet dumps
41
- print "e "
42
- else
43
- g = graph # schema graph
44
- ttl.deleteNode # convert Turtle
45
- ef.w g,true if !ef.e# to JSON (for faster loading)
46
- roonga "schema" # index in rroonga
47
- m={}; puts uri # statistics graph
48
- g.map{|u,_| # each resource
49
- c[u] && # do stats exist?
50
- m[u] = {'uri'=>u, '/frequency' => c[u]}} # add to graph
51
- nt.w E.renderRDF m # store N-triples
52
- schemaLinkSlashURIs # link "Slash-URI" resources to definer
53
- end
54
- end
55
-
56
- def schemaUnindexDoc
57
- unroonga
58
- nt.deleteNode
59
- end
60
-
61
- # make slash-URIs resolvable
62
- def schemaLinkSlashURIs undo=false
63
- return if !ef.e # cache populated?
64
- graph.do{|m| # build graph
65
- m.map{|u,r| # iterate through URIs
66
- r[RDFs+'isDefinedBy'].do{|d| # check for DefinedBy attribute
67
- t = u.E.ef # symlink location
68
- t.dirname.dir # container dir of symlink
69
- if undo
70
- if t.e
71
- t.deleteNode # remove link
72
- puts "-#{t}"
73
- end
74
- else
75
- unless t.e
76
- ef.ln t # add link
77
- puts "#{t} -> #{ef}"
78
- end
79
- end
80
- }}}
81
- rescue Exception => e
82
- puts e
83
- end
84
-
85
- def schemaUnlinkSlashURIs
86
- schemaLinkSlashURIs :undo
87
- end
88
-
89
- # parse gromgull's BTC statistics
90
- def E.schemaStatistics
91
- @gromgull ||=
92
- (data = '/predicates.2010'.E
93
- (puts "curl http://data.whats-your.name/schema/gromgull.gz | zcat > predicates.2010"; exit) unless data.e
94
- # occurrence count :: URI -> int
95
- usage = {}
96
- data.read.each_line{|e|
97
- e.match(/(\d+)[^<]+<([^>]+)>/).do{|r|
98
- usage[r[2]] = r[1].to_i }}
99
- usage)
100
- end
101
-
102
- # parse schema URIs
103
- def E.schemaDocs
104
- @docs ||=
105
- (source = E['http://prefix.cc/popular/all.file.txt']
106
- mirror = E['http://localhost/css/i/prefix.cc.txt']
107
- schemae = (mirror.e ? mirror : source).
108
- read.split("\n"). # each doc
109
- grep(/^[^#]/). # skip commented
110
- map{|t|t.split(/\t/)[1].E}) # URI field
111
- end
112
-
113
- fn '/schema/GET',->e,r{
114
- r.q.merge!({
115
- 'graph'=>'roonga',
116
- 'context'=>'schema',
117
- 'view'=>'search',
118
- 'filter'=>'frag',
119
- 'v'=>'schema',
120
- 'c'=>(r.q.has_key?('q') ? 1000 : 0)
121
- })
122
- e.response
123
- }
124
-
125
- fn 'u/schema/weight',->d,e{
126
- q = e.q['q']
127
- d.keys.map{|k| k.class==String && d[k].class==Hash &&
128
- (s=0
129
- u=k.downcase
130
- d[k]['/frequency'][0].to_i.do{|f|f > 0 && (s=s + (Math.log f))}
131
- s=s+(u.label.match(q.downcase) && 6 ||
132
- q.camelToke.map(&:downcase).map{|c|
133
- u.match(c) && 3 || 0}.sum)
134
- d[k]['score'] = s )}}
135
-
136
- fn 'view/schema',->d,e{
137
- # score resources on popularity, URL friendliness
138
- Fn 'u/schema/weight',d,e
139
- # sort updated response-graph based on score
140
- d = d.select{|u,r|
141
- r['score'] && r['score'].respond_to?(:>)
142
- }.sort_by{|u,r| r['score'] }.reverse
143
-
144
- d.size > 0 &&
145
- (# fit values to CSS range
146
- scale = 255 / d[0][1]['score'].do{|s|s > 0 && s || 1}
147
- [(H.css '/css/schema'),'<table>',
148
- d.map{|u,r|
149
- # score -> normalized score
150
- v = r['score'] * scale
151
- # score -> greyscale value
152
- f = '%02x' % v
153
- # greyscale val -> full CSS
154
- style = 'color:#'+(v > 128 ? '000' : 'fff')+';background-color:#'+f+f+f
155
- # stats on stats
156
- title = r['/frequency'][0].to_s + ' | %.3f'%r['score']
157
-
158
- [{_: :tr, class: :overview, style: style, title: title,
159
- c: [{_: :td, class: :identity,
160
- c: u.E.html},
161
- {_: :td, class: :label,
162
- c: [{_: :span, class: :stats, c: title},
163
- r[RDFs+'label'][0].do{|l|
164
- {_: :a, href: r.uri,class: :label,c: l}}]}]},
165
- {_: :tr, class: :details, style: style, title: title,
166
- c: {_: :td, colspan: 2, class: :describe,
167
- c: [r[RDFs+'comment'][0].do{|l|
168
- {_: :span,class: :comment, c: l}},' ',
169
- {_: :a, href: '/@'+u.sub('#','%23')+'?filter=frag',
170
- c: '&gt;&gt;'}]}}]},'</table>'])}
171
-
172
- end