infod 0.0.1 → 0.0.2

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 (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