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/H/who.rb ADDED
@@ -0,0 +1,30 @@
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
File without changes
data/infod/K.rb CHANGED
@@ -1,10 +1,10 @@
1
+ #watch __FILE__
1
2
  class E
2
3
 
3
- FSbase = `pwd`.chomp
4
- Prefix = '/@' # resolver for non-local and non-HTTP URIs
5
- S = '<>' # path separator
4
+ FSbase = `pwd`.chomp ; BaseLen = FSbase.size
5
+ Prefix = '/@' # non-HTTP URI path resolution-prefix
6
+ S = /\._/ # data path-separator
6
7
 
7
- # frequently-used URIs
8
8
  W3 = 'http://www.w3.org/'
9
9
  Purl = 'http://purl.org/'
10
10
  FOAF = "http://xmlns.com/foaf/0.1/"
@@ -22,13 +22,17 @@ class E
22
22
  Type = W3 + "1999/02/22-rdf-syntax-ns#type"
23
23
  RDFs = W3 + '2000/01/rdf-schema#'
24
24
  HTTP = W3 + '2011/http#'
25
+ Header = W3 + '2011/http-headers#'
25
26
  Posix = W3 + 'ns/posix/'
26
27
  Stat = Posix + 'stat#'
27
28
  Label = RDFs + 'label'
28
29
  EXIF = 'http://www.w3.org/2003/12/exif/ns#'
29
30
  Audio = 'http://www.semanticdesktop.org/ontologies/nid3/#'
31
+ Edit = 'http://buzzword.org.uk/rdf/personal-link-types#edit'
32
+ Render = 'render/'
33
+ Apache = ENV['apache']
34
+ Nginx = ENV['nginx']
30
35
 
31
- # file-name extension -> MIME type
32
36
  MIME={
33
37
  aif: 'audio/aif',
34
38
  ans: 'text/ansi',
@@ -58,12 +62,13 @@ class E
58
62
  mp3: 'audio/mpeg',
59
63
  mp4: 'video/mp4',
60
64
  mpg: 'video/mpg',
61
- n3: 'text/rdf+n3',
65
+ n3: 'text/n3',
62
66
  nfo: 'text/nfo',
63
67
  nt: 'text/ntriples',
64
68
  ntriples: 'text/ntriples',
65
69
  owl: 'application/rdf+xml',
66
70
  pdf: 'application/pdf',
71
+ pl: 'application/perl',
67
72
  png: 'image/png',
68
73
  py: 'application/python',
69
74
  rb: 'application/ruby',
@@ -76,17 +81,20 @@ class E
76
81
  ttl: 'text/turtle',
77
82
  txt: 'text/plain',
78
83
  u: 'application/uri',
84
+ url: 'text/plain',
79
85
  wav: 'audio/wav',
80
86
  wmv: 'video/wmv',
81
87
  xlsx: 'application/excel',
82
88
  }
83
89
 
84
- # MIME type -> triplrFn
90
+ VideoFile = /(avi|flv|mkv|mpg|mp4|wmv)$/i
91
+ AudioFile = /(aif|wav|flac|mp3|m4a|aac|ogg)$/i
92
+
85
93
  MIMEsource={
86
94
  'application/atom+xml' => [:triplrFeed],
87
95
  'application/markdown' => [:triplrMarkdown],
88
96
  'application/org' => [:triplrOrg],
89
- 'application/rdf+xml' => [:triplrRDFformats,:rdfxml],
97
+ 'application/rdf+xml' => [:triplrRDF,:rdfxml],
90
98
  'application/json' => [:triplrJSON],
91
99
  'application/pdf' => [:triplrPDF],
92
100
  'application/textile' => [:triplrTextile],
@@ -95,51 +103,44 @@ class E
95
103
  'audio/mp4' => [:triplrStdOut,'faad -i',Audio],
96
104
  'audio/mpeg' => [:triplrStdOut,'id3info',Audio,/\((.*?)\)$/],
97
105
  'audio' => [:triplrStdOut,'sndfile-info',Audio],
98
- 'image' => [:triplrStdOut,'exiftool',EXIF],
106
+ 'inode/symlink' => [:triplrSymlink],
99
107
  'message/rfc822' => [:triplrMail],
100
108
  'text/ansi' => [:triplrANSI],
101
109
  'text/comma-separated-values'=>[:triplrCSV,/,/],
102
- 'text/html' => [:triplrRDFformats, :rdfa],
103
- 'text/log' => [:triplrLog],
110
+ 'text/log' => [:triplrIRC],
111
+ 'text/man' => [:triplrMan],
104
112
  'text/nfo' => [:triplrHref,'cp437'],
105
- 'text/ntriples' => [:triplrRDFformats, :ntriples],
113
+ 'text/ntriples' => [:triplrRDF, :ntriples],
106
114
  'text/plain' => [:triplrHref],
107
115
  'text/rtf' => [:triplrRTF],
108
116
  'text/semicolon-separated-values'=>[:triplrCSV,/;/],
109
117
  'text/tab-separated-values'=>[:triplrCSV,/\t/],
110
- 'text/turtle' => [:triplrRDFformats,:turtle],
118
+ 'text/turtle' => [:triplrRDF,:turtle],
111
119
  }
112
120
 
113
- # MIME type -> formatted content
114
- Render='render/'
115
- fn Render+'application/ld+json',->d,_=nil{E.renderRDF d, :jsonld}
116
- fn Render+'application/rdf+xml',->d,_=nil{E.renderRDF d, :rdfxml}
117
- fn Render+'text/ntriples',->d,_=nil{E.renderRDF d, :ntriples}
118
- fn Render+'text/turtle', ->d,_=nil{E.renderRDF d, :turtle}
119
- fn Render+'text/rdf+n3', ->d,_=nil{E.renderRDF d, :n3}
120
- fn Render+'text/n3', ->d,_=nil{E.renderRDF d, :n3}
121
-
122
- # render a view even if requested file exists
121
+ # prefer a view even if requested file exists
123
122
  MIMEcook={
124
123
  'application/atom+xml' => true,
125
124
  'application/markdown' => true,
126
- 'application/json' => true,
127
125
  'application/json+rdf' => true,
128
126
  'application/org' => true,
129
127
  'application/textile' => true,
128
+ 'application/uri' => true,
130
129
  'application/word' => true,
130
+ 'inode/symlink' => true,
131
131
  'message/rfc822'=> true,
132
132
  'text/ansi'=>true,
133
133
  'text/log'=>true,
134
+ 'text/man'=>true,
134
135
  'text/nfo'=>true,
135
136
  'text/rtf'=>true,
136
137
  }
137
- %w{c ruby haskell php python}.map{|t|
138
+
139
+ %w{c c++ fortran haskell makefile pascal perl php python ruby}.map{|t|
138
140
  %w{application/ text/x-}.map{|m|
139
141
  MIMEcook[m+t] = true
140
142
  }}
141
143
 
142
- # short -> full URI
143
144
  Abbrev={
144
145
  "dc" => DC,
145
146
  "foaf" => FOAF,
@@ -149,7 +150,7 @@ class E
149
150
  "stat" => Stat,
150
151
  }
151
152
 
152
- # expose these literals as a path-name
153
+ # literal to pathname types
153
154
  Literal={}
154
155
  [Purl+'dc/elements/1.1/date',
155
156
  Date,
@@ -157,41 +158,8 @@ class E
157
158
  Modified,
158
159
  ].map{|f|Literal[f]=true}
159
160
 
160
- def mime
161
- @mime ||= (# dereferenced symlink
162
- f = readlink
163
-
164
- # filename extension
165
- x = f.ext.downcase.to_sym
166
-
167
- # directory?
168
- if d?
169
- "inode/directory"
170
- # local MIME-types table
171
- elsif MIME[x]
172
- # puts "found mime for #{x} -> #{MIME[x]}"
173
- MIME[x]
174
- # Rack MIME-types table
175
- elsif Rack::Mime::MIME_TYPES[t = '.' + x.to_s]
176
- Rack::Mime::MIME_TYPES[t]
177
- # procmail uses a prefix not an extension
178
- elsif f.base.index('msg.')==0
179
- "message/rfc822"
180
- # ask FILE(1)
181
- elsif f.e
182
- `file --mime-type -b #{f.sh}`.chomp
183
- # default
184
- else
185
- "application/octet-stream"
186
- end)
187
- end
188
-
189
161
  def == u
190
162
  to_s == u.to_s
191
163
  end
192
164
 
193
- Nginx = ENV['nginx']
194
- Apache = ENV['apache']
195
- Version = 'http://web.whats-your.name/www/'
196
-
197
165
  end
data/infod/N.rb CHANGED
@@ -1,39 +1,49 @@
1
1
  %w{base64 cgi shellwords}.each{|r|require(r)}
2
2
 
3
3
  def E e
4
- return e if e.class == E
5
- return e unless e
6
4
  E.new e
7
5
  end
8
6
 
9
7
  class E
10
- def E.[] u; E u end
11
- def E e=uri; super e end
12
8
 
13
- attr_reader :uri
14
- def initialize uri; @uri = uri.to_s end
9
+ def E.[] u; u.E end
10
+
11
+ def E arg=nil
12
+ if arg
13
+ E.new arg
14
+ else
15
+ self
16
+ end
17
+ end
15
18
 
16
- def base
17
- File.basename path
19
+ attr_reader :uri
20
+
21
+ def initialize uri
22
+ @uri = uri.to_s
18
23
  end
19
24
 
20
- def bare
21
- base.sub(/\.#{ext}$/,'')
22
- rescue
23
- base
25
+ def basename
26
+ File.basename path
24
27
  end
28
+ alias_method :base, :basename
25
29
 
26
- def docBase
27
- readlink.uri.
28
- split(/#/)[0].E.
29
- do{|d|
30
- d.dirname.as d.bare}
30
+ def barename
31
+ basename.sub(/\.#{ext}$/,'')
32
+ rescue
33
+ basename
31
34
  end
35
+ alias_method :bare, :barename
32
36
 
33
- def ef; @ef ||= docBase.a('.e') end
34
- def nt; @nt ||= docBase.a('.nt') end
35
- def ttl; @ttl ||= docBase.a('.ttl') end
37
+ def ef; @ef ||= docBase.a('.e') end
38
+ def nt; @nt ||= docBase.a('.nt') end
39
+ def ttl; @ttl||= docBase.a('.ttl') end
36
40
 
41
+ def docBase
42
+ uri.split(/#/)[0].E.do{|d|
43
+ d.dirname.as d.bare }
44
+ end
45
+
46
+ # same as above, but w/ URI errors
37
47
  def docBaseURI
38
48
  u = URI uri
39
49
  s = u.scheme
@@ -49,21 +59,50 @@ class E
49
59
  uri.frag
50
60
  end
51
61
 
52
- def docs
53
- (e ? [self] : []). # directly-referenced
54
- concat(docBase.glob ".{e,html,n3,nt,owl,rdf,ttl}"). # docs
55
- concat((d? && uri[-1]=='/') ? c : []) # trailing slash -> children
62
+ def parent
63
+ E Pathname.new(uri).parent
64
+ end
65
+
66
+ def parents
67
+ parent.do{|p|
68
+ p.uri.match(/^[.\/]+$/) ? [p] : [p].concat(p.parents)}
69
+ end
70
+
71
+ def cascade
72
+ [self].concat parents
56
73
  end
57
74
 
58
75
  def dirname
59
- no.dirname.E
76
+ n = node.dirname
77
+ n = '/' if n.to_s.size <= BaseLen
78
+ n.E
60
79
  end
61
-
62
- # generate URL for non-URL identifier (mail ID, Tag URI..)
80
+ alias_method :dir, :dirname
81
+
82
+ # local URL from unlocatable identifier (mail MSGID, etc)
63
83
  def url
64
84
  path? ? uri : Prefix + (CGI.escape uri)
65
- end
66
-
85
+ end
86
+
87
+ # local URL even if locatable-identifier
88
+ def localURL e
89
+ # path
90
+ if uri.index('/') == 0
91
+ uri
92
+ # host match
93
+ elsif uri.index('http://'+e['SERVER_NAME']+'/') == 0
94
+ pathSegment.uri
95
+ # non-local
96
+ else
97
+ Prefix + (CGI.escape uri)
98
+ end
99
+ end
100
+
101
+ def pathSegment
102
+ m = uri.match(/^([a-z]+:\/\/[^\/]+)?(\/.*)/)
103
+ m && m[2] && m[2].E || nil
104
+ end
105
+
67
106
  # URI extension :: E -> string
68
107
  def ext
69
108
  File.extname(uri).tail||''
@@ -77,84 +116,115 @@ class E
77
116
  uri.expand.E
78
117
  end
79
118
 
80
- # concatenate URIs with separator
81
- # s :: E -> E
82
- def s b
83
- u.a E(b).path
119
+ def prependURI u
120
+ E u.to_s + uri
84
121
  end
85
122
 
86
- def prependURI s
87
- (s + uri).E
123
+ def appendURI u
124
+ E uri + u.to_s
88
125
  end
89
126
 
90
- def appendURI s
91
- (uri + s).E
127
+ def appendSlashURI u
128
+ E uri.t + u.to_s
92
129
  end
93
- alias_method :a, :appendURI
94
- alias_method :+, :appendURI
95
130
 
96
- def appendSlashURI s
97
- E uri.t + s
131
+ def concatURI b
132
+ u.appendURI b.E.path
98
133
  end
134
+
135
+ alias_method :a, :appendURI
136
+ alias_method :+, :appendURI
99
137
  alias_method :as, :appendSlashURI
100
138
 
101
- # path? :: E -> Bool
102
139
  def path?
103
140
  uri.path?
104
141
  end
105
142
 
106
- # path :: E -> String
143
+ # URI -> path
107
144
  def path
108
145
  @path ||=
109
- path? ? (uri.match(/^\//) ?
110
- uri : '/'+uri) :
111
- '/E/'+uri.h.dive[0..5]+(Base64.urlsafe_encode64 uri)
146
+ (if path?
147
+ if uri.match /^\//
148
+ uri
149
+ else
150
+ '/' + uri
151
+ end
152
+ else
153
+ '/E/' + uri.h.dive[0..5] + (Base64.urlsafe_encode64 uri)
154
+ end)
112
155
  end
113
156
 
114
157
  def u
115
- @u ||= E (f ? dirname + '/.' + File.basename(path) : path.t + E::S)
158
+ # data-storage path for resource
159
+ @u ||= E (f ? dirname + '/.' + (File.basename path) : path.t + '._')
116
160
  end
117
161
 
118
- # E (_ _ o) -> E o
119
- def ro
120
- uri.split(/#{E::S}\//)[-1].unpath false
162
+ # (_ _ o) -> o
163
+ def innerPath
164
+ (uri.split S)[-1].unpath
121
165
  end
166
+ alias_method :ro, :innerPath
122
167
 
123
168
  def sh
124
169
  d.force_encoding('UTF-8').sh
125
170
  end
126
171
 
127
- # literal -> URI
172
+ # literals to URIs
173
+
174
+ def E.literal o
175
+ E['/'].literal o
176
+ end
177
+
128
178
  def literal o
179
+
180
+ # already a URI
181
+ return self if o.class == E
182
+
183
+ # blob for non-strings
129
184
  return literalBlob o unless o.class == String
185
+
186
+ # whitelisted predicateURIs to paths
130
187
  return literalURI o if (Literal[uri] || o.size<=88) && !o.match(/\//)
188
+
189
+ # string matches URI format
131
190
  return E o if o.match %r{\A[a-z]+://[^\s]+\Z}
191
+
192
+ # blob
132
193
  literalBlob o
194
+
133
195
  end
134
196
 
135
197
  # pathname for short literals
136
198
  def literalURI o
137
- E "/u/"+(Literal[uri] && o.gsub(/[\.:\-T+]/,'/'))+'/'+o
199
+ E "/l/"+(Literal[uri] && o.gsub(/[\.:\-T+]/,'/'))+'/'+o
138
200
  end
139
201
 
140
202
  def literalBlobURI o
141
203
  if o.class == String
142
- E "/blob/"+o.h.dive
204
+ E "/E/blob/"+o.h.dive
143
205
  else
144
- E "/json/"+[o].to_json.h.dive
206
+ E "/E/json/"+[o].to_json.h.dive
145
207
  end
146
208
  end
147
209
 
210
+ def literalBlob o
211
+ u = literalBlobURI o
212
+ u.w o, !o.class == String unless u.f
213
+ end
214
+
148
215
  # spaceship
149
216
  def <=> c
150
217
  to_s <=> c.to_s
151
218
  end
152
219
 
153
- # example: E('wiggly').to_s -> "wiggly"
154
- def to_s # string
220
+ def to_s
155
221
  uri
156
222
  end
157
223
 
224
+ def to_h
225
+ {'uri' => uri}
226
+ end
227
+
158
228
  end
159
229
 
160
230
  class Hash
@@ -199,34 +269,41 @@ class String
199
269
  Shellwords.escape self
200
270
  end
201
271
 
202
- BaseLen = E::FSbase.size.succ
203
-
204
- def pathToURI r = true
205
- self[BaseLen..-1].unpath r
272
+ def unpathFs
273
+ self[E::BaseLen..-1].do{|p|
274
+ (p.match(/^\/([a-z]+:)\/+(.*)/).do{|m|m[1]+'//'+m[2]}||p).E}
206
275
  end
207
276
 
208
- # string -> E || literal
209
- def unpath r=true # dereference literal?
277
+ # path -> URI || literal
278
+ def unpath
210
279
 
211
- if m=(match /^([a-z]+:)\/+(.*)/) # URL
212
- (m[1]+'//'+m[2]).E
280
+ # URI with scheme
281
+ if m = (match /^\/([a-z]+:)\/+(.*)/)
282
+ (m[1] + '//' + m[2]).E
213
283
 
214
- elsif match /^blob/ # string
215
- r ? ('/'+self).E.r : ('/'+self).E
284
+ # String literal in store
285
+ elsif match /^\/E\/blob/
286
+ self.E.r
216
287
 
217
- elsif match /^json/ # JSON
218
- r ? (('/'+self).E.r true) : ('/'+self).E
288
+ # JSON literal in store
289
+ elsif match /^\/E\/json/
290
+ self.E.r true
219
291
 
220
- elsif match /^u\// # trie
221
- r ? (File.basename self) : ('/'+self).E
292
+ # String literal in basename
293
+ elsif match /^\/l\//
294
+ File.basename self
222
295
 
223
- elsif match /^E\/..\/..\// # !fs-compatible URI
224
- self[8..-1].match(/([^.]+)(.*)/).do{|c|
296
+ # URI (opaque)
297
+ elsif match /^\/E\/..\//
298
+ self[9..-1].match(/([^.]+)(.*)/).do{|c|
225
299
  (Base64.urlsafe_decode64 c[1]) + c[2]
226
300
  }.E
227
- else # path
228
- ('/'+self).E
301
+
302
+ # path
303
+ else
304
+ self.E
229
305
  end
306
+
230
307
  end
231
308
 
232
309
  def E