infod 0.0.3.1 → 0.0.3.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.
- data/infod.rb +1 -6
- data/infod/404.rb +3 -4
- data/infod/500.rb +3 -2
- data/infod/GET.rb +23 -14
- data/infod/HEAD.rb +1 -1
- data/infod/HTTP.rb +24 -40
- data/infod/POST.rb +18 -16
- data/infod/audio.rb +12 -4
- data/infod/blog.rb +1 -1
- data/infod/code.rb +2 -2
- data/infod/constants.rb +6 -6
- data/infod/csv.rb +27 -4
- data/infod/edit.rb +58 -42
- data/infod/feed.rb +55 -27
- data/infod/fs.rb +6 -4
- data/infod/glob.rb +3 -4
- data/infod/graph.rb +66 -50
- data/infod/grep.rb +12 -9
- data/infod/groonga.rb +35 -50
- data/infod/html.rb +82 -55
- data/infod/image.rb +1 -1
- data/infod/index.rb +23 -73
- data/infod/infod.rb +1 -6
- data/infod/kv.rb +8 -6
- data/infod/lambda.rb +2 -0
- data/infod/ls.rb +21 -15
- data/infod/mail.rb +36 -27
- data/infod/man.rb +3 -3
- data/infod/microblog.rb +3 -3
- data/infod/mime.rb +1 -0
- data/infod/names.rb +28 -92
- data/infod/page.rb +10 -4
- data/infod/rdf.rb +11 -4
- data/infod/ruby.rb +2 -1
- data/infod/schema.rb +4 -20
- data/infod/sh.rb +3 -5
- data/infod/text.rb +5 -3
- data/infod/threads.rb +12 -13
- data/infod/time.rb +16 -14
- data/infod/webid.rb +0 -0
- metadata +3 -7
- data/infod/PATCH.rb +0 -5
- data/infod/css.rb +0 -21
- data/infod/du.rb +0 -16
- data/infod/json.rb +0 -38
- data/infod/search.rb +0 -16
data/infod/infod.rb
CHANGED
@@ -4,13 +4,12 @@ lambda
|
|
4
4
|
mime
|
5
5
|
404
|
6
6
|
500
|
7
|
+
grep
|
7
8
|
audio
|
8
9
|
blog
|
9
10
|
cal
|
10
11
|
code
|
11
|
-
css
|
12
12
|
csv
|
13
|
-
du
|
14
13
|
edit
|
15
14
|
facets
|
16
15
|
feed
|
@@ -20,7 +19,6 @@ fs
|
|
20
19
|
GET
|
21
20
|
glob
|
22
21
|
graph
|
23
|
-
grep
|
24
22
|
groonga
|
25
23
|
HEAD
|
26
24
|
histogram
|
@@ -28,7 +26,6 @@ html
|
|
28
26
|
HTTP
|
29
27
|
image
|
30
28
|
index
|
31
|
-
json
|
32
29
|
kv
|
33
30
|
ls
|
34
31
|
mail
|
@@ -36,13 +33,11 @@ man
|
|
36
33
|
microblog
|
37
34
|
names
|
38
35
|
page
|
39
|
-
PATCH
|
40
36
|
POST
|
41
37
|
postscript
|
42
38
|
rdf
|
43
39
|
ruby
|
44
40
|
schema
|
45
|
-
search
|
46
41
|
sh
|
47
42
|
text
|
48
43
|
threads
|
data/infod/kv.rb
CHANGED
@@ -21,8 +21,8 @@ class E
|
|
21
21
|
if t.e # old triple exists?
|
22
22
|
t.deleteNode # remove triple
|
23
23
|
indexEdit p,o,'' # unindex
|
24
|
-
end
|
25
|
-
self[p,oO] unless oO.empty? #
|
24
|
+
end # add
|
25
|
+
self[p,oO] unless oO.class==String && oO.empty? # 3rd arg is new value, empty-string -> nil
|
26
26
|
else
|
27
27
|
unless t.e # triple exists?
|
28
28
|
indexEdit p,o,nil # index triple
|
@@ -37,10 +37,12 @@ class E
|
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
|
-
def
|
41
|
-
|
42
|
-
|
43
|
-
|
40
|
+
def triplrDoc &f
|
41
|
+
docBase.glob('#*').map{|s| s.triplrResource &f}
|
42
|
+
end
|
43
|
+
|
44
|
+
def triplrResource
|
45
|
+
properties.map{|p|self[p].map{|o| yield uri, p.uri, o}}
|
44
46
|
end
|
45
47
|
|
46
48
|
def deletePredicate p
|
data/infod/lambda.rb
CHANGED
data/infod/ls.rb
CHANGED
@@ -16,6 +16,8 @@ class E
|
|
16
16
|
F['view/'+MIMEtype+'inode/directory'] = F['view/dir']
|
17
17
|
|
18
18
|
fn 'view/ls',->i,e{
|
19
|
+
e.q['sort'] ||= 'stat:mtime'
|
20
|
+
e.q['reverse'] ||= true
|
19
21
|
dir = e['uri'].E
|
20
22
|
path = dir.pathSegment
|
21
23
|
up = (!path || path.uri == '/') ? '/' : dir.parent.url
|
@@ -30,20 +32,24 @@ class E
|
|
30
32
|
{_: :a, class: :up, href: up+'?view=ls', c: '↑'},
|
31
33
|
{class: :ls, c: (Fn 'view/table',i,e)},'<br clear=all>',
|
32
34
|
{_: :a, class: :down, href: e['uri'].E.url.t, c: '↓'}]}
|
33
|
-
|
34
|
-
# user-patchable default-handler
|
35
|
-
fn '/GET',->e,r{
|
36
|
-
x = 'index.html'
|
37
|
-
i = [e,e.pathSegment].compact.map{|e|e.as x}.find &:e
|
38
|
-
if i
|
39
|
-
if e.uri[-1] == '/' # inside dir?
|
40
|
-
i.env(r).getFile # show index
|
41
|
-
else # descend to indexed dir
|
42
|
-
[301, {Location: e.uri.t}, []]
|
43
|
-
end
|
44
|
-
else
|
45
|
-
# default handler
|
46
|
-
e.response
|
47
|
-
end}
|
48
35
|
|
36
|
+
fn 'protograph/du',->d,q,m{
|
37
|
+
d.pathSegment.do{|path|
|
38
|
+
GREP_DIRS.find{|p|path.uri.match p}.do{|ok|
|
39
|
+
e = [d,path].compact.find &:e
|
40
|
+
q['view'] ||= 'table'
|
41
|
+
q['sort'] = Stat+'size'
|
42
|
+
q['reverse'] = true
|
43
|
+
m[e.uri] = e if e
|
44
|
+
rand.to_s.h}}}
|
45
|
+
|
46
|
+
fn 'graph/du',->e,_,m{
|
47
|
+
`du -a #{m.values[0].sh}`.each_line{|l|
|
48
|
+
s,p = l.chomp.split /\t/ # size, path
|
49
|
+
p = p.unpathFs # path -> URI
|
50
|
+
m[p.uri] = {'uri' => p.uri,
|
51
|
+
Posix+'util#du' => E[p.uri+'?graph=du#du'],
|
52
|
+
Stat+'size' => [s.to_i]}}
|
53
|
+
m }
|
54
|
+
|
49
55
|
end
|
data/infod/mail.rb
CHANGED
@@ -6,9 +6,19 @@ class E
|
|
6
6
|
rescue LoadError => e
|
7
7
|
end
|
8
8
|
|
9
|
-
MessagePath = ->id{
|
10
|
-
|
11
|
-
|
9
|
+
MessagePath = ->id{ h = id.h # hash identifier
|
10
|
+
'/msg/' + h[0..2] + '/' + id}
|
11
|
+
|
12
|
+
GREP_DIRS.push /^\/m\/[^\/]+\// # allow grep within a single address
|
13
|
+
|
14
|
+
F['/m/GET'] = -> e,r{
|
15
|
+
if m = e.pathSegment.uri.match(/^\/m\/([^\/]+)$/)
|
16
|
+
r.q['set'] = 'depth'
|
17
|
+
r.q['view'] ||= 'threads'
|
18
|
+
e.response
|
19
|
+
else
|
20
|
+
false
|
21
|
+
end}
|
12
22
|
|
13
23
|
def triplrTmail &f
|
14
24
|
(TMail::Mail.load node).do{|m| # load
|
@@ -24,49 +34,48 @@ class E
|
|
24
34
|
yield e, Date, m.date.iso8601 if m.date
|
25
35
|
yield e, Title, m.subject.to_utf8
|
26
36
|
yield e, Creator, E[creator]
|
27
|
-
yield e, SIOC+'has_discussion', E[e+'?graph=thread']
|
28
|
-
|
29
|
-
yield creator, SIOC+'name', m.friendly_from.to_utf8
|
37
|
+
yield e, SIOC+'has_discussion', E[e+'?graph=thread&view=timegraph#discussion']
|
38
|
+
yield creator, Name, m.friendly_from.to_utf8
|
30
39
|
yield creator, DC+'identifier', E['mailto:'+from]
|
31
|
-
|
32
|
-
|
33
|
-
yield posts, Type, E[LDP+'Container']
|
34
|
-
yield posts, LDP+'firstPage', E['/index/sioc:has_creator/'+CGI.escape(creator)]
|
35
|
-
yield e, SIOC+'reply_to', E[URI.escape "mailto:#{m.header['x-original-to']||from}?References=<#{e}>&In-Reply-To=<#{e}>&Subject=#{m.subject.to_utf8}"]
|
40
|
+
yield e, SIOC+'reply_to',
|
41
|
+
E[URI.escape("mailto:#{m.header['x-original-to']||from}?References=<#{id}>&In-Reply-To=<#{id}>&Subject=#{m.subject.to_utf8}&")+'#reply']
|
36
42
|
|
37
43
|
%w{to cc bcc}.map{|to|
|
38
44
|
m.send(to).do{|to| to.map{|to|
|
39
45
|
to = to.to_utf8
|
40
|
-
|
41
|
-
|
42
|
-
yield r, SIOC+'container_of', E['/index/sioc:addressed_to/'+CGI.escape(r)]}}}
|
46
|
+
yield e, To, E['/m/'+to+'#'+to]
|
47
|
+
}}}
|
43
48
|
|
44
49
|
%w{in_reply_to references}.map{|ref|
|
45
50
|
m.send(ref).do{|refs| refs.map{|r|
|
46
51
|
yield e, SIOC+'reply_of', E[MessagePath[r[1..-2]]]}}}
|
52
|
+
m.in_reply_to.do{|refs| refs.map{|r|yield e, SIOC+'has_parent', E[MessagePath[r[1..-2]]]}}
|
47
53
|
|
48
|
-
# RDF:HTML
|
54
|
+
# RDF:HTML message-body
|
49
55
|
yield e, Content,
|
50
56
|
H([{_: :pre, class: :mail, style: 'white-space: pre-wrap',
|
51
57
|
c: m.concat_message(e.E,0,&f).gsub(/^\s*(>)(>|\s)*\n/,"").lines.to_a.map{|l| # skip quoted empty-lines
|
52
|
-
l.match(/(^\s*(>|On[^\n]+(said|wrote))[^\n]*)\n/) ? {_: :span, class: :q, c: l} : l #
|
53
|
-
}},
|
54
|
-
{_: :style, c: "pre.mail .q {background-color:#00f;color:#fff}\npre.mail a{background-color:#ef3}\npre.mail img {max-width:100%}"}])}
|
58
|
+
l.match(/(^\s*(>|On[^\n]+(said|wrote))[^\n]*)\n/) ? {_: :span, class: :q, depth: l.scan(/(>)/).size, c: l} : l # quotes
|
59
|
+
}},(H.css '/css/mail',true)])}
|
55
60
|
rescue Exception => e
|
56
61
|
puts e
|
57
62
|
end
|
58
63
|
|
59
64
|
def triplrMailMessage &f
|
60
|
-
|
65
|
+
# indexing function, called on previously-unseen doc-graphs
|
66
|
+
ix = ->doc, graph, host {
|
67
|
+
graph.map{|u,r|
|
68
|
+
a = [] # addresses
|
69
|
+
r[Creator].do{|c|a.concat c}
|
70
|
+
r[To].do{|t|a.concat t}
|
71
|
+
r[Date].do{|t|
|
72
|
+
st = '/'+t[0].gsub('-','/').sub('T','.').sub(/\+.*/,'.'+u.h[0..1]+'.e')
|
73
|
+
a.map{|rel|
|
74
|
+
doc.ln E[rel.uri.split('#')[0]+st]}}}}
|
75
|
+
addDocs :triplrTmail, @r['SERVER_NAME'], [SIOC+'reply_of'], ix, &f
|
61
76
|
end
|
62
|
-
=begin
|
63
|
-
there's another mail library called Mail, as of v2.5.4 takes 50x as long as tmail (apt-get install ruby-tmail)
|
64
|
-
HEAD 200 http://m/m/2013/12/01/?nocache=&triplr=triplrMail curl/7.33.0 5.4003388
|
65
|
-
HEAD 200 http://m/m/2013/12/01/?nocache=&triplr=triplrTmail curl/7.33.0 0.1198720
|
66
|
-
|
67
|
-
almost a copy of above works but identifiers are not wrapped in <> - with caching it might be fast enough..
|
68
77
|
|
69
|
-
=
|
78
|
+
F['view/'+MIMEtype+'message/rfc822'] = NullView # hide containing file in default render
|
70
79
|
|
71
80
|
end
|
72
81
|
|
@@ -94,7 +103,7 @@ module TMail
|
|
94
103
|
else # just a part
|
95
104
|
unicode_body.do{|b|
|
96
105
|
if content_type && content_type.match(/html/)
|
97
|
-
|
106
|
+
E::F['cleanHTML'][b]
|
98
107
|
else
|
99
108
|
b.hrefs true
|
100
109
|
end}
|
data/infod/man.rb
CHANGED
@@ -16,13 +16,13 @@ class E
|
|
16
16
|
if !name || name.empty? || name.match(/\//)
|
17
17
|
if section
|
18
18
|
# enumerate section children
|
19
|
-
|
19
|
+
body = H [H.css('/css/man'),{_: :style, c: "a {background-color: #{E.cs}}"},
|
20
20
|
Pathname(manPath+'/man'+section).c.map{|p|
|
21
21
|
n = p.basename.to_s.sub /\.[0-9][a-z]*\...$/,''
|
22
22
|
}.group_by{|e|e[0].match(/[a-zA-Z]/) ? e[0].downcase : '0-9'}.sort.map{|g,m|
|
23
23
|
[{_: :h3, c: g},
|
24
|
-
m.map{|n|[{_: :a, href: '/man/'+section+'/'+n, c: n },' ']}]}
|
25
|
-
|
24
|
+
m.map{|n|[{_: :a, href: '/man/'+section+'/'+n, c: n },' ']}]}]
|
25
|
+
[200, {'Content-Type'=>'text/html; charset=utf-8'}, [body]]
|
26
26
|
else
|
27
27
|
e.response
|
28
28
|
end
|
data/infod/microblog.rb
CHANGED
@@ -26,7 +26,7 @@ class E
|
|
26
26
|
|
27
27
|
def tw g
|
28
28
|
no.readlines.shuffle.each_slice(22){|s|
|
29
|
-
E['https://twitter.com/search/realtime?q='+s.map{|u|'from:'+u.chomp}.intersperse('+OR+').join].
|
29
|
+
E['https://twitter.com/search/realtime?q='+s.map{|u|'from:'+u.chomp}.intersperse('+OR+').join].addDocs :triplrTweets, g, nil, FeedArchiver}
|
30
30
|
end
|
31
31
|
|
32
32
|
def triplrTweets
|
@@ -36,7 +36,7 @@ class E
|
|
36
36
|
yield s, Type, E[SIOCt+'MicroblogPost']
|
37
37
|
yield s, Type, E[SIOC+'Post']
|
38
38
|
yield s, Creator, E(base+'/'+t.css('.username b')[0].inner_text)
|
39
|
-
yield s,
|
39
|
+
yield s, Name,t.css('.fullname')[0].inner_text
|
40
40
|
yield s, Atom+"/link/image", E(t.css('.avatar')[0].attr('src'))
|
41
41
|
yield s, Date, Time.at(t.css('[data-time]')[0].attr('data-time').to_i).iso8601
|
42
42
|
content = t.css('.tweet-text')[0]
|
@@ -56,7 +56,7 @@ class E
|
|
56
56
|
[r[Date][0].match(/T([0-9:]{5})/).do{|m|m[1]},
|
57
57
|
{_: :span, :class => :nick, c: {_: :a, href: r[Atom+'/link/alternate'].do{|a|a[0].uri}||r.url,
|
58
58
|
c: [r[Atom+"/link/image"].do{|p| {_: :img, src: p[0].uri, style: "#{rand(2).zero? ? 'left' : 'right'}: 0"}},
|
59
|
-
{_: :span, c: r[
|
59
|
+
{_: :span, c: r[Name]||r[Creator]||'#'}]}},' ',
|
60
60
|
{_: :span, :class => :tw, # skip redundant title fields
|
61
61
|
c: [((r[Title].to_s == r[Content].to_s || r.uri.match(/twitter/)) && '' ||
|
62
62
|
{_: :a, :class => :title, href: r.url, c: r[Title]}), # skip quoted mail-lines & abbreviate
|
data/infod/mime.rb
CHANGED
data/infod/names.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
|
-
%w{
|
1
|
+
%w{cgi shellwords}.each{|r|require(r)}
|
2
2
|
|
3
3
|
class E
|
4
4
|
|
5
5
|
attr_reader :uri
|
6
6
|
alias_method :url, :uri
|
7
|
+
alias_method :maybeURI, :uri
|
7
8
|
|
8
9
|
def env r=nil
|
9
10
|
r ? (@r = r
|
@@ -58,7 +59,7 @@ class E
|
|
58
59
|
end
|
59
60
|
alias_method :dir, :dirname
|
60
61
|
|
61
|
-
# add hostname to URI if missing
|
62
|
+
# add hostname to URI (if missing)
|
62
63
|
def hostURL e
|
63
64
|
host = 'http://'+e['SERVER_NAME']
|
64
65
|
if uri.index('/') == 0
|
@@ -70,15 +71,12 @@ class E
|
|
70
71
|
|
71
72
|
# pointer to local data about global URI
|
72
73
|
def localURL e
|
73
|
-
|
74
|
-
|
75
|
-
uri
|
76
|
-
# host match
|
74
|
+
if uri.index('/') == 0
|
75
|
+
uri # already a local path
|
77
76
|
elsif e && uri.index('http://'+e['SERVER_NAME']+'/') == 0
|
78
|
-
pathSegment.uri
|
79
|
-
# non-local
|
77
|
+
pathSegment.uri # host match, unchanged local path
|
80
78
|
else
|
81
|
-
|
79
|
+
'/' + uri # URI -> local path
|
82
80
|
end
|
83
81
|
end
|
84
82
|
|
@@ -87,7 +85,6 @@ class E
|
|
87
85
|
m && m[2] && m[2].E || nil
|
88
86
|
end
|
89
87
|
|
90
|
-
# URI extension :: E -> string
|
91
88
|
def ext
|
92
89
|
File.extname(uri).tail||''
|
93
90
|
end
|
@@ -124,39 +121,25 @@ class E
|
|
124
121
|
alias_method :+, :appendURI
|
125
122
|
alias_method :as, :appendSlashURI
|
126
123
|
|
127
|
-
def path?
|
128
|
-
uri.path?
|
129
|
-
end
|
130
|
-
|
131
124
|
def shortPath
|
132
125
|
@shortPath ||=
|
133
|
-
(if
|
134
|
-
|
135
|
-
uri
|
136
|
-
else
|
137
|
-
'/' + uri.shorten
|
138
|
-
end
|
126
|
+
(if uri.match /^\//
|
127
|
+
uri
|
139
128
|
else
|
140
|
-
'/
|
129
|
+
'/' + uri.shorten
|
141
130
|
end)
|
142
131
|
end
|
143
132
|
|
144
|
-
# URI -> path
|
145
133
|
def path
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
'/' + uri
|
152
|
-
end
|
153
|
-
else
|
154
|
-
'/E/' + uri.h.dive[0..5] + (Base64.urlsafe_encode64 uri)
|
155
|
-
end)
|
134
|
+
if uri.match /^\//
|
135
|
+
uri
|
136
|
+
else
|
137
|
+
'/' + uri
|
138
|
+
end
|
156
139
|
end
|
157
140
|
|
158
141
|
def u
|
159
|
-
#
|
142
|
+
# path for data about this resource
|
160
143
|
@u ||= E (f ? dirname + '/.' + (File.basename path) : path.t + '._')
|
161
144
|
end
|
162
145
|
|
@@ -170,56 +153,22 @@ class E
|
|
170
153
|
d.force_encoding('UTF-8').sh
|
171
154
|
end
|
172
155
|
|
173
|
-
# literals to URIs
|
174
|
-
# currently used for iso8601 dates mapping to paths, so date-range queries (depth-first subtrees) can be done w/ dir/fs tools
|
175
|
-
# could also use as a "trie" for autocomplete + sorted-strings
|
176
156
|
def E.literal o
|
177
|
-
|
157
|
+
''.E.literal o
|
178
158
|
end
|
179
|
-
|
180
|
-
Literal={}
|
181
|
-
[Purl+'dc/elements/1.1/date',
|
182
|
-
Date,DC+'created',DC+'modified',
|
183
|
-
].map{|f|Literal[f]=true}
|
184
159
|
|
185
160
|
def literal o
|
186
|
-
|
187
|
-
# already a URI
|
188
161
|
return o if o.class == E
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
return literalURI o if (Literal[uri] || o.size<=88) && !o.match(/\//)
|
195
|
-
|
196
|
-
# string matches URI format
|
197
|
-
return E o if o.match %r{\A[a-z]+://[^\s]+\Z}
|
198
|
-
|
199
|
-
# blob
|
200
|
-
literalBlob o
|
201
|
-
|
202
|
-
end
|
203
|
-
|
204
|
-
# pathname for short literals
|
205
|
-
def literalURI o
|
206
|
-
E "/l/"+o.gsub(/[\.:\-T+]/,'/')+'/'+o if Literal[uri] && o
|
207
|
-
end
|
208
|
-
|
209
|
-
def literalBlobURI o
|
210
|
-
if o.class == String
|
211
|
-
E "/E/blob/"+o.h.dive
|
212
|
-
else
|
213
|
-
E "/E/json/"+[o].to_json.h.dive
|
214
|
-
end
|
215
|
-
end
|
216
|
-
|
217
|
-
def literalBlob o
|
218
|
-
u = literalBlobURI o
|
162
|
+
u = (if o.class == String
|
163
|
+
E "/E/blob/"+o.h.dive
|
164
|
+
else
|
165
|
+
E "/E/json/"+[o].to_json.h.dive
|
166
|
+
end)
|
219
167
|
u.w o, !o.class == String unless u.f
|
168
|
+
u
|
220
169
|
end
|
221
170
|
|
222
|
-
# spaceship
|
171
|
+
# spaceship comparison-operator
|
223
172
|
def <=> c
|
224
173
|
to_s <=> c.to_s
|
225
174
|
end
|
@@ -232,7 +181,7 @@ class E
|
|
232
181
|
{'uri' => uri}
|
233
182
|
end
|
234
183
|
|
235
|
-
#
|
184
|
+
# internal pathnames not on the web (cached representations, index databases)
|
236
185
|
F['/E/GET'] = F[E404]
|
237
186
|
|
238
187
|
end
|
@@ -242,6 +191,7 @@ class Hash
|
|
242
191
|
self["uri"]||""
|
243
192
|
end
|
244
193
|
alias_method :url, :uri
|
194
|
+
alias_method :maybeURI, :uri
|
245
195
|
def label
|
246
196
|
self[E::Label] || uri.label
|
247
197
|
end
|
@@ -274,7 +224,7 @@ class String
|
|
274
224
|
self )
|
275
225
|
end
|
276
226
|
|
277
|
-
# shrink URI to qname/CURIE/
|
227
|
+
# shrink URI to qname/CURIE/prefixed identifier
|
278
228
|
def shorten
|
279
229
|
E::Prefix.map{|p,f|
|
280
230
|
return p + ':' + self[f.size..-1] if (index f) == 0
|
@@ -298,16 +248,10 @@ class String
|
|
298
248
|
if m = (match /^\/([a-z]+:)\/+(.*)/)
|
299
249
|
(m[1] + '//' + m[2]).E
|
300
250
|
|
301
|
-
#
|
251
|
+
# prefix-shortened URI
|
302
252
|
elsif m = (match /^\/([^\/:]+:[^\/]+)/)
|
303
253
|
m[1].expand.E
|
304
254
|
|
305
|
-
# opaque URI w/ optional extension
|
306
|
-
elsif match /^\/E\/..\//
|
307
|
-
self[9..-1].match(/([^.]+)(.*)/).do{|c|
|
308
|
-
(Base64.urlsafe_decode64 c[1]) + c[2]
|
309
|
-
}.E
|
310
|
-
|
311
255
|
# String literal
|
312
256
|
elsif match /^\/E\/blob/
|
313
257
|
self.E.r
|
@@ -316,10 +260,6 @@ class String
|
|
316
260
|
elsif match /^\/E\/json/
|
317
261
|
self.E.r true
|
318
262
|
|
319
|
-
# literal in basename
|
320
|
-
elsif match /^\/l\//
|
321
|
-
File.basename self
|
322
|
-
|
323
263
|
# plain path
|
324
264
|
else
|
325
265
|
self.E
|
@@ -331,10 +271,6 @@ class String
|
|
331
271
|
E.new self
|
332
272
|
end
|
333
273
|
|
334
|
-
def path?
|
335
|
-
(match /^(\.|\/|https?:\/)/) && true || false
|
336
|
-
end
|
337
|
-
|
338
274
|
def frag
|
339
275
|
split(/#/).pop()
|
340
276
|
end
|